static int vidioc_try_fmt(struct file *file, void *prv, struct v4l2_format *f) { struct g2d_fmt *fmt; enum v4l2_field *field; fmt = find_fmt(f); if (!fmt) return -EINVAL; field = &f->fmt.pix.field; if (*field == V4L2_FIELD_ANY) *field = V4L2_FIELD_NONE; else if (*field != V4L2_FIELD_NONE) return -EINVAL; if (f->fmt.pix.width > MAX_WIDTH) f->fmt.pix.width = MAX_WIDTH; if (f->fmt.pix.height > MAX_HEIGHT) f->fmt.pix.height = MAX_HEIGHT; if (f->fmt.pix.width < 1) f->fmt.pix.width = 1; if (f->fmt.pix.height < 1) f->fmt.pix.height = 1; f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; return 0; }
int my_printf(char *format, ...) { va_list ap; unsigned int i; unsigned int width; va_start(ap, format); i = 0; width = 0; while (format[i] != '\0') { if (format[i] != '%') my_putchar(format[i]); else { i = i + 1; while (format[i] == ' ') i = i + 1; if (format[i] >= '0' && format[i] <= '9') { width = find_width(format, i); i = i + my_nbrlen(width); } if (format[i] == '%') my_putchar(format[i]); else find_fmt(ap, format, i, width); } i = i + 1; } va_end(ap); return (0); }
static int gsc_capture_s_fmt_mplane(struct file *file, void *fh, struct v4l2_format *f) { struct gsc_dev *gsc = video_drvdata(file); struct gsc_ctx *ctx = gsc->cap.ctx; struct gsc_frame *frame; struct v4l2_pix_format_mplane *pix; int i, ret = 0; ret = gsc_capture_try_fmt_mplane(file, fh, f); if (ret) return ret; if (vb2_is_streaming(&gsc->cap.vbq)) { gsc_err("queue (%d) busy", f->type); return -EBUSY; } frame = &ctx->d_frame; pix = &f->fmt.pix_mp; frame->fmt = find_fmt(&pix->pixelformat, NULL, 0); if (!frame->fmt) return -EINVAL; for (i = 0; i < frame->fmt->nr_comp; i++) frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height; gsc_set_frame_size(frame, pix->width, pix->height); gsc_info("f_w: %d, f_h: %d", frame->f_width, frame->f_height); return 0; }
void print_data(string tag, string type, int *dims) { string fmt; size_t dlen; char buf[BUFLEN]; /* danger: buffer overflow */ byte *dat, *dp; bool Qprint; Qprint = !(*testtag && streq(tag,testtag)==0); /* if only print testtag... */ fmt = find_fmt(type); dlen = get_dlen(instr, tag); dat = (byte*) allocate(dlen); get_data_sub(instr, tag, type, dat, dims, FALSE); if (streq(type, CharType) && Qprint) (void) outstr(dims != NULL ? "\"" : "\'"); for (dp = dat; dp < dat + dlen; ) { /* loop over data array */ if (streq(type, AnyType)) { /* output generic data? */ sprintf(buf, fmt, *((byte *) dp)); dp += sizeof(byte); } else if (streq(type, CharType)) { /* output readable chars? */ sprintf(buf, fmt, *((char *) dp)); dp += sizeof(char); } else if (streq(type, ByteType)) { /* output bytes of data? */ sprintf(buf, fmt, *((byte *) dp)); dp += sizeof(byte); } else if (streq(type, ShortType)) { /* output short integers? */ sprintf(buf, fmt, *((short *) dp)); dp += sizeof(short); } else if (streq(type, IntType)) { /* output standard ints? */ sprintf(buf, fmt, *((int *) dp)); dp += sizeof(int); } else if (streq(type, LongType)) { /* output long integers? */ sprintf(buf, fmt, *((long *) dp)); dp += sizeof(long); } else if (streq(type, HalfpType)) { /* output short int? */ sprintf(buf, fmt, *((short *) dp)); dp += sizeof(short); } else if (streq(type, FloatType)) { /* output floating point? */ sprintf(buf, fmt, *((float *) dp)); dp += sizeof(float); } else if (streq(type, DoubleType)) { /* output double numbers? */ sprintf(buf, fmt, *((double *) dp)); dp += sizeof(double); } else error("print_data: type %s unknown\n", type); if (Qprint) if (! outstr(buf)) break; } if (streq(type, CharType) && Qprint) (void) outstr(dims != NULL ? "\"" : "\'"); if (xml && Qprint) { sprintf(buf," </%s>",tag); outstr(buf); } free((char *)dat); }
int gsc_enum_fmt_mplane(struct v4l2_fmtdesc *f) { const struct gsc_fmt *fmt; fmt = find_fmt(NULL, NULL, f->index); if (!fmt) return -EINVAL; strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->pixelformat; return 0; }
static int gsc_m2m_s_fmt_mplane(struct file *file, void *fh, struct v4l2_format *f) { struct gsc_ctx *ctx = fh_to_ctx(fh); struct vb2_queue *vq; struct gsc_frame *frame; struct v4l2_pix_format_mplane *pix; int i, ret = 0; ret = gsc_m2m_try_fmt_mplane(file, fh, f); if (ret) return ret; vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); if (vb2_is_streaming(vq)) { pr_err("queue (%d) busy", f->type); return -EBUSY; } if (V4L2_TYPE_IS_OUTPUT(f->type)) frame = &ctx->s_frame; else frame = &ctx->d_frame; pix = &f->fmt.pix_mp; frame->fmt = find_fmt(&pix->pixelformat, NULL, 0); frame->colorspace = pix->colorspace; if (!frame->fmt) return -EINVAL; for (i = 0; i < frame->fmt->num_planes; i++) frame->payload[i] = pix->plane_fmt[i].sizeimage; gsc_set_frame_size(frame, pix->width, pix->height); if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) gsc_ctx_state_lock_set(GSC_PARAMS | GSC_DST_FMT, ctx); else gsc_ctx_state_lock_set(GSC_PARAMS | GSC_SRC_FMT, ctx); pr_debug("f_w: %d, f_h: %d", frame->f_width, frame->f_height); return 0; }
static int vidioc_s_fmt(struct file *file, void *prv, struct v4l2_format *f) { struct g2d_ctx *ctx = prv; struct g2d_dev *dev = ctx->dev; struct vb2_queue *vq; struct g2d_frame *frm; struct g2d_fmt *fmt; int ret = 0; /* Adjust all values accordingly to the hardware capabilities * and chosen format. */ ret = vidioc_try_fmt(file, prv, f); if (ret) return ret; vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); if (vb2_is_busy(vq)) { v4l2_err(&dev->v4l2_dev, "queue (%d) bust\n", f->type); return -EBUSY; } frm = get_frame(ctx, f->type); if (IS_ERR(frm)) return PTR_ERR(frm); fmt = find_fmt(f); if (!fmt) return -EINVAL; frm->width = f->fmt.pix.width; frm->height = f->fmt.pix.height; frm->size = f->fmt.pix.sizeimage; /* Reset crop settings */ frm->o_width = 0; frm->o_height = 0; frm->c_width = frm->width; frm->c_height = frm->height; frm->right = frm->width; frm->bottom = frm->height; frm->fmt = fmt; frm->stride = f->fmt.pix.bytesperline; return 0; }
static void gsc_cap_try_format(struct gsc_dev *gsc, struct v4l2_subdev_fh *fh, unsigned int pad, struct v4l2_mbus_framefmt *fmt, enum v4l2_subdev_format_whence which) { struct gsc_fmt *gfmt; gfmt = find_fmt(NULL, &fmt->code, 0); WARN_ON(!gfmt); if (pad == GSC_PAD_SINK) { struct gsc_ctx *ctx = gsc->cap.ctx; struct gsc_frame *frame = &ctx->s_frame; frame->fmt = gfmt; } gsc_cap_check_limit_size(gsc, pad, fmt); fmt->colorspace = V4L2_COLORSPACE_JPEG; fmt->field = V4L2_FIELD_NONE; }
int gsc_try_fmt_mplane(struct gsc_ctx *ctx, struct v4l2_format *f) { struct gsc_dev *gsc = ctx->gsc_dev; struct gsc_variant *variant = gsc->variant; struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; const struct gsc_fmt *fmt; u32 max_w, max_h, mod_x, mod_y; u32 min_w, min_h, tmp_w, tmp_h; int i; pr_debug("user put w: %d, h: %d", pix_mp->width, pix_mp->height); fmt = find_fmt(&pix_mp->pixelformat, NULL, 0); if (!fmt) { pr_err("pixelformat format (0x%X) invalid\n", pix_mp->pixelformat); return -EINVAL; } if (pix_mp->field == V4L2_FIELD_ANY) pix_mp->field = V4L2_FIELD_NONE; else if (pix_mp->field != V4L2_FIELD_NONE) { pr_debug("Not supported field order(%d)\n", pix_mp->field); return -EINVAL; } max_w = variant->pix_max->target_rot_dis_w; max_h = variant->pix_max->target_rot_dis_h; mod_x = ffs(variant->pix_align->org_w) - 1; if (is_yuv420(fmt->color)) mod_y = ffs(variant->pix_align->org_h) - 1; else mod_y = ffs(variant->pix_align->org_h) - 2; if (V4L2_TYPE_IS_OUTPUT(f->type)) { min_w = variant->pix_min->org_w; min_h = variant->pix_min->org_h; } else { min_w = variant->pix_min->target_rot_dis_w; min_h = variant->pix_min->target_rot_dis_h; pix_mp->colorspace = ctx->out_colorspace; } pr_debug("mod_x: %d, mod_y: %d, max_w: %d, max_h = %d", mod_x, mod_y, max_w, max_h); /* To check if image size is modified to adjust parameter against hardware abilities */ tmp_w = pix_mp->width; tmp_h = pix_mp->height; v4l_bound_align_image(&pix_mp->width, min_w, max_w, mod_x, &pix_mp->height, min_h, max_h, mod_y, 0); if (tmp_w != pix_mp->width || tmp_h != pix_mp->height) pr_debug("Image size has been modified from %dx%d to %dx%d\n", tmp_w, tmp_h, pix_mp->width, pix_mp->height); pix_mp->num_planes = fmt->num_planes; if (V4L2_TYPE_IS_OUTPUT(f->type)) ctx->out_colorspace = pix_mp->colorspace; for (i = 0; i < pix_mp->num_planes; ++i) { struct v4l2_plane_pix_format *plane_fmt = &pix_mp->plane_fmt[i]; u32 bpl = plane_fmt->bytesperline; if (fmt->num_comp == 1 && /* Packed */ (bpl == 0 || (bpl * 8 / fmt->depth[i]) < pix_mp->width)) bpl = pix_mp->width * fmt->depth[i] / 8; if (fmt->num_comp > 1 && /* Planar */ (bpl == 0 || bpl < pix_mp->width)) bpl = pix_mp->width; if (i != 0 && fmt->num_comp == 3) bpl /= 2; plane_fmt->bytesperline = bpl; plane_fmt->sizeimage = max(pix_mp->width * pix_mp->height * fmt->depth[i] / 8, plane_fmt->sizeimage); pr_debug("[%d]: bpl: %d, sizeimage: %d", i, bpl, pix_mp->plane_fmt[i].sizeimage); } return 0; }
int gsc_try_fmt_mplane(struct gsc_ctx *ctx, struct v4l2_format *f) { struct gsc_dev *gsc = ctx->gsc_dev; struct gsc_variant *variant = gsc->variant; struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; struct gsc_fmt *fmt; u32 max_w, max_h, mod_x, mod_y; u32 min_w, min_h, tmp_w, tmp_h; int i; gsc_dbg("user put w: %d, h: %d", pix_mp->width, pix_mp->height); fmt = find_fmt(&pix_mp->pixelformat, NULL, 0); if (!fmt) { gsc_err("pixelformat format (0x%X) invalid\n", pix_mp->pixelformat); return -EINVAL; } if (pix_mp->field == V4L2_FIELD_ANY) pix_mp->field = V4L2_FIELD_NONE; else if (pix_mp->field != V4L2_FIELD_NONE) { gsc_err("Not supported field order(%d)\n", pix_mp->field); return -EINVAL; } max_w = variant->pix_max->target_rot_dis_w; max_h = variant->pix_max->target_rot_dis_h; if (V4L2_TYPE_IS_OUTPUT(f->type)) { mod_x = ffs(variant->pix_align->org_w) - 1; if (is_yuv420(fmt->color)) mod_y = ffs(variant->pix_align->org_h) - 1; else mod_y = ffs(variant->pix_align->org_h) - 2; min_w = variant->pix_min->org_w; min_h = variant->pix_min->org_h; } else { mod_x = ffs(variant->pix_align->org_w) - 1; if (is_yuv420(fmt->color)) mod_y = ffs(variant->pix_align->org_h) - 1; else mod_y = ffs(variant->pix_align->org_h) - 2; min_w = variant->pix_min->target_rot_dis_w; min_h = variant->pix_min->target_rot_dis_h; } gsc_dbg("mod_x: %d, mod_y: %d, max_w: %d, max_h = %d", mod_x, mod_y, max_w, max_h); /* To check if image size is modified to adjust parameter against hardware abilities */ tmp_w = pix_mp->width; tmp_h = pix_mp->height; v4l_bound_align_image(&pix_mp->width, min_w, max_w, mod_x, &pix_mp->height, min_h, max_h, mod_y, 0); if (tmp_w != pix_mp->width || tmp_h != pix_mp->height) gsc_info("Image size has been modified from %dx%d to %dx%d", tmp_w, tmp_h, pix_mp->width, pix_mp->height); pix_mp->num_planes = fmt->num_planes; if (ctx->gsc_ctrls.csc_eq_mode->val) ctx->gsc_ctrls.csc_eq->val = (pix_mp->width >= 1280) ? 1 : 0; if (ctx->gsc_ctrls.csc_eq->val) /* HD */ pix_mp->colorspace = V4L2_COLORSPACE_REC709; else /* SD */ pix_mp->colorspace = V4L2_COLORSPACE_SMPTE170M; for (i = 0; i < pix_mp->num_planes; ++i) { int bpl = (pix_mp->width * fmt->depth[i]) >> 3; pix_mp->plane_fmt[i].bytesperline = bpl; pix_mp->plane_fmt[i].sizeimage = bpl * pix_mp->height; gsc_dbg("[%d]: bpl: %d, sizeimage: %d", i, bpl, pix_mp->plane_fmt[i].sizeimage); } return 0; }