int32_t scale_cfg(enum scale_cfg_id id, void *param) { enum scale_drv_rtn rtn = SCALE_RTN_SUCCESS; switch (id) { case SCALE_INPUT_SIZE: { struct scale_size *size = (struct scale_size*)param; uint32_t reg_val = 0; SCALE_CHECK_PARAM_ZERO_POINTER(param); SCALE_TRACE("SCALE DRV: SCALE_INPUT_SIZE {%d %d} \n", size->w, size->h); if (size->w > SCALE_FRAME_WIDTH_MAX || size->h > SCALE_FRAME_HEIGHT_MAX) { rtn = SCALE_RTN_SRC_SIZE_ERR; } else { reg_val = size->w | (size->h << 16); REG_WR(SCALE_SRC_SIZE, reg_val); g_path->input_size.w = size->w; g_path->input_size.h = size->h; } break; } case SCALE_INPUT_RECT: { struct scale_rect *rect = (struct scale_rect*)param; uint32_t reg_val = 0; SCALE_CHECK_PARAM_ZERO_POINTER(param); SCALE_TRACE("SCALE DRV: SCALE_PATH_INPUT_RECT {%d %d %d %d} \n", rect->x, rect->y, rect->w, rect->h); if (rect->x > SCALE_FRAME_WIDTH_MAX || rect->y > SCALE_FRAME_HEIGHT_MAX || rect->w > SCALE_FRAME_WIDTH_MAX || rect->h > SCALE_FRAME_HEIGHT_MAX) { rtn = SCALE_RTN_TRIM_SIZE_ERR; } else { reg_val = rect->x | (rect->y << 16); REG_WR(SCALE_TRIM_START, reg_val); reg_val = rect->w | (rect->h << 16); REG_WR(SCALE_TRIM_SIZE, reg_val); memcpy((void*)&g_path->input_rect, (void*)rect, sizeof(struct scale_rect)); } break; } case SCALE_INPUT_FORMAT: { enum scale_fmt format = *(enum scale_fmt*)param; SCALE_CHECK_PARAM_ZERO_POINTER(param); g_path->input_format = format; if (SCALE_YUV422 == format || SCALE_YUV420 == format || SCALE_YUV420_3FRAME == format || SCALE_YUV400 == format) { REG_MWR(SCALE_CFG, (3 << 11), g_path->input_format << 11); REG_MWR(SCALE_CFG, (1 << 5), 0 << 5); } else if (SCALE_RGB565 == format) { REG_OWR(SCALE_CFG, (1 << 13)); REG_OWR(SCALE_CFG, (1 << 5)); } else if (SCALE_RGB888 == format) { REG_MWR(SCALE_CFG, (1 << 13), (0 << 13)); REG_OWR(SCALE_CFG, (1 << 5)); } else { rtn = SCALE_RTN_IN_FMT_ERR; g_path->input_format = SCALE_FTM_MAX; } break; } case SCALE_INPUT_ADDR: { struct scale_addr *p_addr = (struct scale_addr*)param; SCALE_CHECK_PARAM_ZERO_POINTER(param); if (SCALE_YUV_ADDR_INVALIDE(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) { rtn = SCALE_RTN_ADDR_ERR; } else { g_path->input_addr.yaddr = p_addr->yaddr; g_path->input_addr.uaddr = p_addr->uaddr; g_path->input_addr.vaddr = p_addr->vaddr; REG_WR(SCALE_FRM_IN_Y, p_addr->yaddr); REG_WR(SCALE_FRM_IN_U, p_addr->uaddr); REG_WR(SCALE_FRM_IN_V, p_addr->vaddr); } break; } case SCALE_INPUT_ENDIAN: { struct scale_endian_sel *endian = (struct scale_endian_sel*)param; SCALE_CHECK_PARAM_ZERO_POINTER(param); if (endian->y_endian >= SCALE_ENDIAN_MAX || endian->uv_endian >= SCALE_ENDIAN_MAX) { rtn = SCALE_RTN_ENDIAN_ERR; } else { REG_MWR(SCALE_ENDIAN_SEL, 3, endian->y_endian); REG_MWR(SCALE_ENDIAN_SEL, 3 << 2, endian->uv_endian << 2); } break; } case SCALE_OUTPUT_SIZE: { struct scale_size *size = (struct scale_size*)param; uint32_t reg_val = 0; SCALE_CHECK_PARAM_ZERO_POINTER(param); SCALE_TRACE("SCALE DRV: SCALE_OUTPUT_SIZE {%d %d} \n", size->w, size->h); if (size->w > SCALE_FRAME_WIDTH_MAX || size->h > SCALE_FRAME_HEIGHT_MAX) { rtn = SCALE_RTN_SRC_SIZE_ERR; } else { reg_val = size->w | (size->h << 16); REG_WR(SCALE_DST_SIZE, reg_val); g_path->output_size.w = size->w; g_path->output_size.h = size->h; } break; } case SCALE_OUTPUT_FORMAT: { enum scale_fmt format = *(enum scale_fmt*)param; SCALE_CHECK_PARAM_ZERO_POINTER(param); g_path->output_format = format; if (SCALE_YUV422 == format) { REG_MWR(SCALE_CFG, (3 << 6), 0 << 6); } else if (SCALE_YUV420 == format) { REG_MWR(SCALE_CFG, (3 << 6), 1 << 6); } else if (SCALE_RGB565 == format) { REG_MWR(SCALE_CFG, (3 << 6), 2 << 6); } else { rtn = SCALE_RTN_OUT_FMT_ERR; g_path->output_format = SCALE_FTM_MAX; } break; } case SCALE_OUTPUT_ADDR: { struct scale_addr *p_addr = (struct scale_addr*)param; SCALE_CHECK_PARAM_ZERO_POINTER(param); if (SCALE_YUV_ADDR_INVALIDE(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) { rtn = SCALE_RTN_ADDR_ERR; } else { g_path->output_addr.yaddr = p_addr->yaddr; g_path->output_addr.uaddr = p_addr->uaddr; REG_WR(SCALE_FRM_OUT_Y, p_addr->yaddr); REG_WR(SCALE_FRM_OUT_U, p_addr->uaddr); } break; } case SCALE_OUTPUT_ENDIAN: { struct scale_endian_sel *endian = (struct scale_endian_sel*)param; SCALE_CHECK_PARAM_ZERO_POINTER(param); if (endian->y_endian >= SCALE_ENDIAN_MAX || endian->uv_endian >= SCALE_ENDIAN_MAX) { rtn = SCALE_RTN_ENDIAN_ERR; } else { REG_MWR(SCALE_ENDIAN_SEL, (3 << 4), endian->y_endian << 4); REG_MWR(SCALE_ENDIAN_SEL, (3 << 6), endian->uv_endian << 6); } break; } case SCALE_TEMP_BUFF: { struct scale_addr *p_addr = (struct scale_addr*)param; SCALE_CHECK_PARAM_ZERO_POINTER(param); if (SCALE_YUV_ADDR_INVALIDE(p_addr->yaddr, p_addr->uaddr, p_addr->vaddr)) { rtn = SCALE_RTN_ADDR_ERR; } else { g_path->temp_buf_src = 1; g_path->temp_buf_addr.yaddr = p_addr->yaddr; g_path->temp_buf_addr.uaddr = p_addr->uaddr; g_path->temp_buf_addr.vaddr = p_addr->vaddr; REG_WR(SCALE_FRM_SWAP_Y, p_addr->yaddr); REG_WR(SCALE_FRM_SWAP_U, p_addr->uaddr); REG_WR(SCALE_FRM_LINE, p_addr->vaddr); } break; } case SCALE_SCALE_MODE: { enum scle_mode mode = *(enum scle_mode*)param; if (mode >= SCALE_MODE_MAX) { rtn = SCALE_RTN_MODE_ERR; } else { g_path->scale_mode = mode; if (SCALE_MODE_NORMAL == mode) { REG_MWR(SCALE_CFG, (1 << 4), (0 << 4)); } else { REG_OWR(SCALE_CFG, (1 << 4)); } } break; } case SCALE_SLICE_SCALE_HEIGHT: { uint32_t height = *(uint32_t*)param; SCALE_CHECK_PARAM_ZERO_POINTER(param); if (height > SCALE_FRAME_HEIGHT_MAX || (height % SCALE_SLICE_HEIGHT_ALIGNED)) { rtn = SCALE_RTN_PARA_ERR; } else { g_path->slice_height = height; REG_MWR(SCALE_SLICE_VER, 0x3FF, height); } break; } case SCALE_START: { rtn = scale_start(); break; } case SCALE_CONTINUE: { rtn = scale_continue(); break; } case SCALE_STOP: { rtn = scale_stop(); break; } default: rtn = SCALE_RTN_IO_ID_ERR; break; } return -rtn; }
int tag_value_parse(tag_t *tag, const char *val, tag_value_t *tval, char *buf, tagvalue_cmp_t cmp) { if (!val) return 1; if (!*val && tag->valuetype != VT_NONE && cmp == CMP_EQ) { tval->v_str = tag_value_null_marker; return 0; } switch (tag->valuetype) { case VT_WORD: tval->v_str = buf ? val : mm_strdup(val); return 0; break; case VT_STRING: tval->v_str = str_enc2str(val, buf); if (!tval->v_str) return 1; return 0; break; case VT_INT: if (!tv_parser_int64_t(val, &tval->val.v_int, &tval->fuzz.f_int, cmp)) { tval->v_str = 0; return 0; } break; case VT_UINT: if (!tv_parser_uint64_t(val, &tval->val.v_uint, &tval->fuzz.f_uint, cmp)) { tval->v_str = 0; return 0; } break; case VT_FLOAT: case VT_F_STOP: case VT_STOP: if (!tv_parser_double(val, &tval->val.v_double, &tval->fuzz.f_double, cmp)) { if (buf) { tval->v_str = val; } else { tval->v_str = mm_strdup(val); } if (tag->valuetype == VT_F_STOP) { scale_f_stop(tval); } else if (tag->valuetype == VT_STOP) { scale_stop(tval); } return 0; } break; case VT_DATETIME: if (!tv_parser_datetime(val, &tval->val.v_datetime, &tval->fuzz.f_datetime, cmp)) { if (buf) { tval->v_str = val; } else { tval->v_str = mm_strdup(val); } return 0; } break; case VT_GPS: if (!tv_parser_gps(val, &tval->val.v_gps, &tval->fuzz.f_gps)) { if (buf) { tval->v_str = val; } else { tval->v_str = mm_strdup(val); } return 0; } break; default: // VT_NONE, or bad value break; } return 1; }