xref: /rockchip-linux_mpp/mpp/vproc/iep2/iep2_osd.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2020 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #include "iep2_gmv.h"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <stdio.h>
20*437bfbebSnyanmisaka #include <string.h>
21*437bfbebSnyanmisaka #include <stdlib.h>
22*437bfbebSnyanmisaka 
23*437bfbebSnyanmisaka #include "mpp_common.h"
24*437bfbebSnyanmisaka #include "mpp_buffer.h"
25*437bfbebSnyanmisaka 
26*437bfbebSnyanmisaka #include "iep2_api.h"
27*437bfbebSnyanmisaka 
iep2_sort(uint32_t bin[],uint32_t map[],int size)28*437bfbebSnyanmisaka void iep2_sort(uint32_t bin[], uint32_t map[], int size)
29*437bfbebSnyanmisaka {
30*437bfbebSnyanmisaka     int i, m, n;
31*437bfbebSnyanmisaka     uint32_t *dat = malloc(size * sizeof(uint32_t));
32*437bfbebSnyanmisaka 
33*437bfbebSnyanmisaka     for (i = 0; i < size; ++i) {
34*437bfbebSnyanmisaka         map[i] = i;
35*437bfbebSnyanmisaka         dat[i] = bin[i];
36*437bfbebSnyanmisaka     }
37*437bfbebSnyanmisaka 
38*437bfbebSnyanmisaka     for (m = 0; m < size; ++m) {
39*437bfbebSnyanmisaka         int max = m;
40*437bfbebSnyanmisaka         uint32_t temp;
41*437bfbebSnyanmisaka         int p;
42*437bfbebSnyanmisaka 
43*437bfbebSnyanmisaka         for (n = m + 1; n < size; ++n)
44*437bfbebSnyanmisaka             if (dat[n] > dat[max])
45*437bfbebSnyanmisaka                 max = n;
46*437bfbebSnyanmisaka         // Put found minimum element in its place
47*437bfbebSnyanmisaka         temp = dat[m];
48*437bfbebSnyanmisaka         p = map[m];
49*437bfbebSnyanmisaka 
50*437bfbebSnyanmisaka         map[m] = map[max];
51*437bfbebSnyanmisaka         map[max] = p;
52*437bfbebSnyanmisaka         dat[m] = dat[max];
53*437bfbebSnyanmisaka         dat[max] = temp;
54*437bfbebSnyanmisaka     }
55*437bfbebSnyanmisaka 
56*437bfbebSnyanmisaka     free(dat);
57*437bfbebSnyanmisaka }
58*437bfbebSnyanmisaka 
iep2_osd_check(int8_t * mv,int w,int sx,int ex,int sy,int ey,int * mvx)59*437bfbebSnyanmisaka static int iep2_osd_check(int8_t *mv, int w, int sx, int ex, int sy, int ey,
60*437bfbebSnyanmisaka                           int *mvx)
61*437bfbebSnyanmisaka {
62*437bfbebSnyanmisaka     /* (28 + 27) * 4 + 1 */
63*437bfbebSnyanmisaka     uint32_t hist[221];
64*437bfbebSnyanmisaka     uint32_t map[221];
65*437bfbebSnyanmisaka     int total = (ey - sy + 1) * (ex - sx + 1);
66*437bfbebSnyanmisaka     int non_zero = 0;
67*437bfbebSnyanmisaka     int domin = 0;
68*437bfbebSnyanmisaka     int i, j;
69*437bfbebSnyanmisaka 
70*437bfbebSnyanmisaka     memset(hist, 0, sizeof(hist));
71*437bfbebSnyanmisaka 
72*437bfbebSnyanmisaka     for (i = sy; i <= ey; ++i) {
73*437bfbebSnyanmisaka         for (j = sx; j <= ex; ++j) {
74*437bfbebSnyanmisaka             int8_t v = mv[i * w + j];
75*437bfbebSnyanmisaka             uint32_t idx = v + 28 * 4;
76*437bfbebSnyanmisaka 
77*437bfbebSnyanmisaka             if (idx >= MPP_ARRAY_ELEMS(hist)) {
78*437bfbebSnyanmisaka                 mpp_log("invalid mv at (%d, %d)\n", j, i);
79*437bfbebSnyanmisaka                 continue;
80*437bfbebSnyanmisaka             }
81*437bfbebSnyanmisaka             hist[idx]++;
82*437bfbebSnyanmisaka         }
83*437bfbebSnyanmisaka     }
84*437bfbebSnyanmisaka 
85*437bfbebSnyanmisaka     non_zero = total - hist[28 * 4];
86*437bfbebSnyanmisaka 
87*437bfbebSnyanmisaka     iep2_sort(hist, map, MPP_ARRAY_ELEMS(hist));
88*437bfbebSnyanmisaka 
89*437bfbebSnyanmisaka     domin = hist[map[0]];
90*437bfbebSnyanmisaka     if (map[0] + 1 < MPP_ARRAY_ELEMS(hist))
91*437bfbebSnyanmisaka         domin += hist[map[0] + 1];
92*437bfbebSnyanmisaka     if (map[0] >= 1)
93*437bfbebSnyanmisaka         domin += hist[map[0] - 1];
94*437bfbebSnyanmisaka 
95*437bfbebSnyanmisaka     iep_dbg_trace("total tiles in current osd: %d, non-zero %d\n",
96*437bfbebSnyanmisaka                   total, non_zero);
97*437bfbebSnyanmisaka 
98*437bfbebSnyanmisaka     if (domin * 4 < non_zero * 3) {
99*437bfbebSnyanmisaka         iep_dbg_trace("main mv %d count %d not dominant\n",
100*437bfbebSnyanmisaka                       map[0] - 28 * 4, domin);
101*437bfbebSnyanmisaka         return 0;
102*437bfbebSnyanmisaka     }
103*437bfbebSnyanmisaka 
104*437bfbebSnyanmisaka     *mvx = map[0] - 28 * 4;
105*437bfbebSnyanmisaka 
106*437bfbebSnyanmisaka     return 1;
107*437bfbebSnyanmisaka }
108*437bfbebSnyanmisaka 
iep2_set_osd(struct iep2_api_ctx * ctx,struct mv_list * ls)109*437bfbebSnyanmisaka void iep2_set_osd(struct iep2_api_ctx *ctx, struct mv_list *ls)
110*437bfbebSnyanmisaka {
111*437bfbebSnyanmisaka     uint32_t i, j;
112*437bfbebSnyanmisaka     int idx = 0;
113*437bfbebSnyanmisaka 
114*437bfbebSnyanmisaka     int sx[8];
115*437bfbebSnyanmisaka     int ex[8];
116*437bfbebSnyanmisaka     int sy[8];
117*437bfbebSnyanmisaka     int ey[8];
118*437bfbebSnyanmisaka 
119*437bfbebSnyanmisaka     uint32_t osd_tile_cnt = 0;
120*437bfbebSnyanmisaka     int mvx;
121*437bfbebSnyanmisaka     int8_t *pmv = mpp_buffer_get_ptr(ctx->mv_buf);
122*437bfbebSnyanmisaka 
123*437bfbebSnyanmisaka     memset(ls, 0, sizeof(*ls));
124*437bfbebSnyanmisaka 
125*437bfbebSnyanmisaka     for (i = 0; i < ctx->output.dect_osd_cnt; ++i) {
126*437bfbebSnyanmisaka         sx[i] = ctx->output.x_sta[i];
127*437bfbebSnyanmisaka         ex[i] = ctx->output.x_end[i];
128*437bfbebSnyanmisaka         sy[i] = ctx->output.y_sta[i];
129*437bfbebSnyanmisaka         ey[i] = ctx->output.y_end[i];
130*437bfbebSnyanmisaka     }
131*437bfbebSnyanmisaka 
132*437bfbebSnyanmisaka     /* Hardware isn't supporting subtitle regions overlap. */
133*437bfbebSnyanmisaka     for (i = 0; i < ctx->output.dect_osd_cnt; ++i) {
134*437bfbebSnyanmisaka         for (j = i + 1; j < ctx->output.dect_osd_cnt; ++j) {
135*437bfbebSnyanmisaka             if (sy[j] == ey[i]) {
136*437bfbebSnyanmisaka                 if (ex[i] - sx[i] > ex[j] - sx[j]) {
137*437bfbebSnyanmisaka                     sy[j]++;
138*437bfbebSnyanmisaka                 } else {
139*437bfbebSnyanmisaka                     ey[i]--;
140*437bfbebSnyanmisaka                 }
141*437bfbebSnyanmisaka             } else {
142*437bfbebSnyanmisaka                 break;
143*437bfbebSnyanmisaka             }
144*437bfbebSnyanmisaka         }
145*437bfbebSnyanmisaka     }
146*437bfbebSnyanmisaka 
147*437bfbebSnyanmisaka     for (i = 0; i < ctx->output.dect_osd_cnt; ++i) {
148*437bfbebSnyanmisaka         if (!iep2_osd_check(pmv, ctx->params.tile_cols,
149*437bfbebSnyanmisaka                             sx[i], ex[i], sy[i], ey[i], &mvx))
150*437bfbebSnyanmisaka             continue;
151*437bfbebSnyanmisaka 
152*437bfbebSnyanmisaka         ctx->params.osd_x_sta[idx] = sx[i];
153*437bfbebSnyanmisaka         ctx->params.osd_x_end[idx] = ex[i];
154*437bfbebSnyanmisaka         ctx->params.osd_y_sta[idx] = sy[i];
155*437bfbebSnyanmisaka         ctx->params.osd_y_end[idx] = ey[i];
156*437bfbebSnyanmisaka 
157*437bfbebSnyanmisaka         osd_tile_cnt += (ex[i] - sx[i] + 1) * (ey[i] - sy[i] + 1);
158*437bfbebSnyanmisaka 
159*437bfbebSnyanmisaka         ls->mv[idx] = mvx;
160*437bfbebSnyanmisaka         ls->vld[idx] = 1;
161*437bfbebSnyanmisaka 
162*437bfbebSnyanmisaka         iep_dbg_trace("[%d] from [%d,%d][%d,%d] to [%d,%d][%d,%d] mv %d\n", i,
163*437bfbebSnyanmisaka                       sx[i], ex[i], sy[i], ey[i],
164*437bfbebSnyanmisaka                       ctx->params.osd_x_sta[idx], ctx->params.osd_x_end[idx],
165*437bfbebSnyanmisaka                       ctx->params.osd_y_sta[idx], ctx->params.osd_y_end[idx],
166*437bfbebSnyanmisaka                       ls->mv[idx]);
167*437bfbebSnyanmisaka         idx++;
168*437bfbebSnyanmisaka     }
169*437bfbebSnyanmisaka 
170*437bfbebSnyanmisaka     ctx->params.osd_area_num = idx;
171*437bfbebSnyanmisaka     ls->idx = idx;
172*437bfbebSnyanmisaka 
173*437bfbebSnyanmisaka     iep_dbg_trace("osd tile count %d comb %d\n",
174*437bfbebSnyanmisaka                   osd_tile_cnt, ctx->output.out_osd_comb_cnt);
175*437bfbebSnyanmisaka     if (osd_tile_cnt * 2 > ctx->output.out_osd_comb_cnt * 3) {
176*437bfbebSnyanmisaka         memset(ctx->params.comb_osd_vld, 0, sizeof(ctx->params.comb_osd_vld));
177*437bfbebSnyanmisaka     } else {
178*437bfbebSnyanmisaka         memset(ctx->params.comb_osd_vld, 1, sizeof(ctx->params.comb_osd_vld));
179*437bfbebSnyanmisaka     }
180*437bfbebSnyanmisaka }
181*437bfbebSnyanmisaka 
182