From ea7f45aba5ce96f659ebc30a9ad7ab4fa476edc8 Mon Sep 17 00:00:00 2001 From: Martin Pulec Date: Fri, 17 Jun 2016 10:40:30 +0200 Subject: [PATCH] Resize cap. filter: fixed parsing 720x576i option * there was a bug resulting in refusig 720x576i option * similarly 'p' suffix can be used to override original interlacing setting --- src/capture_filter/resize.cpp | 106 +++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 34 deletions(-) diff --git a/src/capture_filter/resize.cpp b/src/capture_filter/resize.cpp index 51bc7c46a..18a48ff25 100644 --- a/src/capture_filter/resize.cpp +++ b/src/capture_filter/resize.cpp @@ -70,14 +70,29 @@ static int init(struct module *parent, const char *cfg, void **state); static void done(void *state); static struct video_frame *filter(void *state, struct video_frame *in); +struct resize_param { + enum resize_mode { + NONE, + USE_FRACTION, + USE_DIMENSIONS, + } mode; + union { + struct { + int num; + int denom; + }; + struct { + int target_width; + int target_height; + }; + }; + bool force_interlaced, force_progressive; +}; + struct state_resize { - int num; - int denom; - double scale_factor; - int target_width, target_height; + struct resize_param param; struct video_frame *frame; struct video_desc saved_desc; - bool force_interlaced; }; static void usage() { @@ -88,14 +103,14 @@ static void usage() { printf("\tresize:x\n\n"); printf("Scaling examples:\n" "\tresize:1/2 - downscale input frame size by scale factor of 2\n" + "\tresize:1280x720 - scales input to 1280x720\n" "\tresize:720x576i - scales input to PAL (overrides interlacing setting)\n"); } static int init(struct module * /* parent */, const char *cfg, void **state) { - int n = 0, w = 0, h = 0; - int denom = 1; - bool force_interlaced = false; + struct resize_param param{}; + if(cfg) { char *endptr; if(strcasecmp(cfg, "help") == 0) { @@ -103,47 +118,68 @@ static int init(struct module * /* parent */, const char *cfg, void **state) return 1; } if (strchr(cfg, 'x')) { - w = strtol(cfg, &endptr, 10); + param.mode = resize_param::resize_mode::USE_DIMENSIONS; + param.target_width = strtol(cfg, &endptr, 10); errno = 0; - h = strtol(strchr(cfg, 'x') + 1, &endptr, 10); + param.target_height = strtol(strchr(cfg, 'x') + 1, &endptr, 10); if (errno != 0) { perror("strtol"); usage(); return -1; } - if (*endptr == 'i') { - force_interlaced = true; - } } else { - n = strtol(cfg, &endptr, 10); + param.mode = resize_param::resize_mode::USE_FRACTION; + param.num = strtol(cfg, &endptr, 10); if(strchr(cfg, '/')) { - denom = strtol(strchr(cfg, '/') + 1, &endptr, 10); + param.denom = strtol(strchr(cfg, '/') + 1, &endptr, 10); + } else { + param.denom = 1; } } + if (*endptr == 'i' || *endptr == 'p') { + if (*endptr == 'i') { + param.force_interlaced = true; + } else { + param.force_progressive = true; + } + endptr += 1; + } + if (*endptr != '\0') { + log_msg(LOG_LEVEL_ERROR, "[RESIZE ERROR] Unrecognized part of config string: %s\n", endptr); usage(); return -1; } } else { + log_msg(LOG_LEVEL_ERROR, "[RESIZE ERROR] No configuration!\n"); usage(); return -1; } - if((n <= 0 || denom <= 0) && ((w <= 0) || (h <= 0))){ - printf("\n[RESIZE ERROR] resize factors must be greater than zero!\n"); + // check validity of options + switch (param.mode) { + case resize_param::resize_mode::USE_FRACTION: + if (param.num <= 0 || param.denom <= 0) { + log_msg(LOG_LEVEL_ERROR, "\n[RESIZE ERROR] resize factors must be greater than zero!\n"); + usage(); + return -1; + } + break; + case resize_param::resize_mode::USE_DIMENSIONS: + if (param.target_width <= 0 || param.target_height <= 0) { + log_msg(LOG_LEVEL_ERROR, "\n[RESIZE ERROR] Targed widht and height must be greater than zero!\n"); + usage(); + return -1; + } + break; + default: usage(); return -1; } struct state_resize *s = (state_resize*) calloc(1, sizeof(struct state_resize)); - s->num = n; - s->denom = denom; - s->scale_factor = (double)s->num/s->denom; - s->force_interlaced = force_interlaced; - - s->target_width = w; - s->target_height = h; + s->param = param; *state = s; return 0; @@ -165,31 +201,33 @@ static struct video_frame *filter(void *state, struct video_frame *in) if (!video_desc_eq(video_desc_from_frame(in), s->saved_desc)) { struct video_desc desc = video_desc_from_frame(in); - if (s->target_width != 0) { - desc.width = s->target_width; - desc.height = s->target_height; + if (s->param.mode == resize_param::resize_mode::USE_DIMENSIONS) { + desc.width = s->param.target_width; + desc.height = s->param.target_height; } else { - desc.width = in->tiles[0].width * s->num / s->denom; - desc.height = in->tiles[0].height * s->num / s->denom; + desc.width = in->tiles[0].width * s->param.num / s->param.denom; + desc.height = in->tiles[0].height * s->param.num / s->param.denom; } desc.color_spec = RGB; s->frame = vf_alloc_desc_data(desc); - if (s->force_interlaced) { + if (s->param.force_interlaced) { s->frame->interlacing = INTERLACED_MERGED; + } else if (s->param.force_progressive) { + s->frame->interlacing = PROGRESSIVE; } s->saved_desc = video_desc_from_frame(in); printf("[resize filter] resizing from %dx%d to %dx%d\n", in->tiles[0].width, in->tiles[0].height, s->frame->tiles[0].width, s->frame->tiles[0].height); } for(i=0; iframe->tile_count;i++){ - if (s->target_width != 0) { - res = resize_frame(in->tiles[i].data, in->color_spec, s->frame->tiles[i].data, in->tiles[i].width, in->tiles[i].height, s->target_width, s->target_height); + if (s->param.mode == resize_param::resize_mode::USE_DIMENSIONS) { + res = resize_frame(in->tiles[i].data, in->color_spec, s->frame->tiles[i].data, in->tiles[i].width, in->tiles[i].height, s->param.target_width, s->param.target_height); } else { - res = resize_frame(in->tiles[i].data, in->color_spec, s->frame->tiles[i].data, in->tiles[i].width, in->tiles[i].height, s->scale_factor); + res = resize_frame(in->tiles[i].data, in->color_spec, s->frame->tiles[i].data, in->tiles[i].width, in->tiles[i].height, (double)s->param.num/s->param.denom); } if(res!=0){ - error_msg("\n[RESIZE ERROR] Unable to resize with scale factor configured [%d/%d] in tile number %d\n", s->num, s->denom, i); + error_msg("\n[RESIZE ERROR] Unable to resize with scale factor configured [%d/%d] in tile number %d\n", s->param.num, s->param.denom, i); error_msg("\t\t No scale factor applied at all. No frame returns...\n"); return NULL; }