/* * Copyright 2020 Rockchip Electronics Co. LTD * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iep2_gmv.h" #include #include #include #include "mpp_common.h" #include "mpp_buffer.h" #include "iep2_api.h" void iep2_sort(uint32_t bin[], uint32_t map[], int size) { int i, m, n; uint32_t *dat = malloc(size * sizeof(uint32_t)); for (i = 0; i < size; ++i) { map[i] = i; dat[i] = bin[i]; } for (m = 0; m < size; ++m) { int max = m; uint32_t temp; int p; for (n = m + 1; n < size; ++n) if (dat[n] > dat[max]) max = n; // Put found minimum element in its place temp = dat[m]; p = map[m]; map[m] = map[max]; map[max] = p; dat[m] = dat[max]; dat[max] = temp; } free(dat); } static int iep2_osd_check(int8_t *mv, int w, int sx, int ex, int sy, int ey, int *mvx) { /* (28 + 27) * 4 + 1 */ uint32_t hist[221]; uint32_t map[221]; int total = (ey - sy + 1) * (ex - sx + 1); int non_zero = 0; int domin = 0; int i, j; memset(hist, 0, sizeof(hist)); for (i = sy; i <= ey; ++i) { for (j = sx; j <= ex; ++j) { int8_t v = mv[i * w + j]; uint32_t idx = v + 28 * 4; if (idx >= MPP_ARRAY_ELEMS(hist)) { mpp_log("invalid mv at (%d, %d)\n", j, i); continue; } hist[idx]++; } } non_zero = total - hist[28 * 4]; iep2_sort(hist, map, MPP_ARRAY_ELEMS(hist)); domin = hist[map[0]]; if (map[0] + 1 < MPP_ARRAY_ELEMS(hist)) domin += hist[map[0] + 1]; if (map[0] >= 1) domin += hist[map[0] - 1]; iep_dbg_trace("total tiles in current osd: %d, non-zero %d\n", total, non_zero); if (domin * 4 < non_zero * 3) { iep_dbg_trace("main mv %d count %d not dominant\n", map[0] - 28 * 4, domin); return 0; } *mvx = map[0] - 28 * 4; return 1; } void iep2_set_osd(struct iep2_api_ctx *ctx, struct mv_list *ls) { uint32_t i, j; int idx = 0; int sx[8]; int ex[8]; int sy[8]; int ey[8]; uint32_t osd_tile_cnt = 0; int mvx; int8_t *pmv = mpp_buffer_get_ptr(ctx->mv_buf); memset(ls, 0, sizeof(*ls)); for (i = 0; i < ctx->output.dect_osd_cnt; ++i) { sx[i] = ctx->output.x_sta[i]; ex[i] = ctx->output.x_end[i]; sy[i] = ctx->output.y_sta[i]; ey[i] = ctx->output.y_end[i]; } /* Hardware isn't supporting subtitle regions overlap. */ for (i = 0; i < ctx->output.dect_osd_cnt; ++i) { for (j = i + 1; j < ctx->output.dect_osd_cnt; ++j) { if (sy[j] == ey[i]) { if (ex[i] - sx[i] > ex[j] - sx[j]) { sy[j]++; } else { ey[i]--; } } else { break; } } } for (i = 0; i < ctx->output.dect_osd_cnt; ++i) { if (!iep2_osd_check(pmv, ctx->params.tile_cols, sx[i], ex[i], sy[i], ey[i], &mvx)) continue; ctx->params.osd_x_sta[idx] = sx[i]; ctx->params.osd_x_end[idx] = ex[i]; ctx->params.osd_y_sta[idx] = sy[i]; ctx->params.osd_y_end[idx] = ey[i]; osd_tile_cnt += (ex[i] - sx[i] + 1) * (ey[i] - sy[i] + 1); ls->mv[idx] = mvx; ls->vld[idx] = 1; iep_dbg_trace("[%d] from [%d,%d][%d,%d] to [%d,%d][%d,%d] mv %d\n", i, sx[i], ex[i], sy[i], ey[i], ctx->params.osd_x_sta[idx], ctx->params.osd_x_end[idx], ctx->params.osd_y_sta[idx], ctx->params.osd_y_end[idx], ls->mv[idx]); idx++; } ctx->params.osd_area_num = idx; ls->idx = idx; iep_dbg_trace("osd tile count %d comb %d\n", osd_tile_cnt, ctx->output.out_osd_comb_cnt); if (osd_tile_cnt * 2 > ctx->output.out_osd_comb_cnt * 3) { memset(ctx->params.comb_osd_vld, 0, sizeof(ctx->params.comb_osd_vld)); } else { memset(ctx->params.comb_osd_vld, 1, sizeof(ctx->params.comb_osd_vld)); } }