static void mxr_vp_fix_geometry(struct mxr_layer *layer, enum mxr_geometry_stage stage, unsigned long flags) { struct mxr_geometry *geo = &layer->geo; struct mxr_crop *src = &geo->src; struct mxr_crop *dst = &geo->dst; unsigned long x_center, y_center; switch (stage) { case MXR_GEOMETRY_SINK: /* nothing to be fixed here */ case MXR_GEOMETRY_COMPOSE: /* remember center of the area */ x_center = dst->x_offset + dst->width / 2; y_center = dst->y_offset + dst->height / 2; /* ensure that compose is reachable using 16x scaling */ dst->width = clamp(dst->width, 8U, 16 * src->full_width); dst->height = clamp(dst->height, 1U, 16 * src->full_height); /* setup offsets */ dst->x_offset = do_center(x_center, dst->width, dst->full_width, flags); dst->y_offset = do_center(y_center, dst->height, dst->full_height, flags); flags = 0; /* remove possible MXR_NO_OFFSET flag */ /* fall through */ case MXR_GEOMETRY_CROP: /* remember center of the area */ x_center = src->x_offset + src->width / 2; y_center = src->y_offset + src->height / 2; /* ensure scaling is between 0.25x .. 16x */ src->width = clamp(src->width, round_up(dst->width / 16, 4), dst->width * 4); src->height = clamp(src->height, round_up(dst->height / 16, 4), dst->height * 4); /* hardware limits */ src->width = clamp(src->width, 32U, 2047U); src->height = clamp(src->height, 4U, 2047U); /* setup offsets */ src->x_offset = do_center(x_center, src->width, src->full_width, flags); src->y_offset = do_center(y_center, src->height, src->full_height, flags); /* setting scaling ratio */ geo->x_ratio = (src->width << 16) / dst->width; geo->y_ratio = (src->height << 16) / dst->height; /* fall through */ case MXR_GEOMETRY_SOURCE: src->full_width = clamp(src->full_width, ALIGN(src->width + src->x_offset, 8), 8192U); src->full_height = clamp(src->full_height, src->height + src->y_offset, 8192U); }; }
static void mxr_graph_fix_geometry(struct mxr_layer *layer, enum mxr_geometry_stage stage, unsigned long flags) { struct mxr_geometry *geo = &layer->geo; struct mxr_crop *src = &geo->src; struct mxr_crop *dst = &geo->dst; unsigned int x_center, y_center; switch (stage) { case MXR_GEOMETRY_SINK: /* nothing to be fixed here */ flags = 0; /* fall through */ case MXR_GEOMETRY_COMPOSE: /* remember center of the area */ x_center = dst->x_offset + dst->width / 2; y_center = dst->y_offset + dst->height / 2; /* round up/down to 2 multiple depending on flags */ if (flags & V4L2_SEL_FLAG_LE) { dst->width = round_down(dst->width, 2); dst->height = round_down(dst->height, 2); } else { dst->width = round_up(dst->width, 2); dst->height = round_up(dst->height, 2); } /* assure that compose rect is inside display area */ dst->width = min(dst->width, dst->full_width); dst->height = min(dst->height, dst->full_height); /* ensure that compose is reachable using 2x scaling */ dst->width = min(dst->width, 2 * src->full_width); dst->height = min(dst->height, 2 * src->full_height); /* setup offsets */ dst->x_offset = do_center(x_center, dst->width, dst->full_width, flags); dst->y_offset = do_center(y_center, dst->height, dst->full_height, flags); flags = 0; /* fall through */ case MXR_GEOMETRY_CROP: /* remember center of the area */ x_center = src->x_offset + src->width / 2; y_center = src->y_offset + src->height / 2; /* ensure that cropping area lies inside the buffer */ if (src->full_width < dst->width) src->width = dst->width / 2; else src->width = closest(src->width, dst->width / 2, dst->width, flags); if (src->width == dst->width) geo->x_ratio = 0; else geo->x_ratio = 1; if (src->full_height < dst->height) src->height = dst->height / 2; else src->height = closest(src->height, dst->height / 2, dst->height, flags); if (src->height == dst->height) geo->y_ratio = 0; else geo->y_ratio = 1; /* setup offsets */ src->x_offset = do_center(x_center, src->width, src->full_width, flags); src->y_offset = do_center(y_center, src->height, src->full_height, flags); flags = 0; /* fall through */ case MXR_GEOMETRY_SOURCE: src->full_width = clamp_val(src->full_width, src->width + src->x_offset, 32767); src->full_height = clamp_val(src->full_height, src->height + src->y_offset, 2047); } }
static void parse_cmdline(int argc, char * const argv[]) { int ch; int index = 0; struct option options[] = { {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, {"geometry", required_argument, NULL, 'g'}, {"resolution", required_argument, NULL, 'r'}, {"center", required_argument, NULL, 'c'}, {"width", required_argument, NULL, 'w'}, {"height", required_argument, NULL, 'H'}, {"method", required_argument, NULL, 'm'}, {"nthreads", required_argument, NULL, 'n'}, {"output", required_argument, NULL, 'o'}, }; while ((ch = getopt_long(argc, argv, "hc:H:m:n:o:r:w:g:V", options, &index)) != -1) { switch (ch) { case 'h': do_usage(argv[0], 0); break; case 'V': do_version(argv[0]); break; case 'g': do_geometry(argv[0], optarg); break; case 'r': do_resolution(argv[0], optarg); break; case 'c': do_center(argv[0], optarg); break; case 'w': do_width(argv[0], optarg); break; case 'H': do_height(argv[0], optarg); break; case 'm': do_method(argv[0], optarg); break; case 'n': do_nthreads(argv[0], optarg); break; case 'o': do_output(argv[0], optarg); break; default: do_usage(argv[0], 1); } } if (plot == NULL) do_method(argv[0], "generic"); if (!output) { fprintf(stderr, "no output file.\n"); exit(1); } }