static int cx18_try_ctrl(struct file *file, void *fh, struct v4l2_ext_control *vctrl) { struct v4l2_queryctrl qctrl; const char **menu_items = NULL; int err; qctrl.id = vctrl->id; err = cx18_queryctrl(file, fh, &qctrl); if (err) return err; if (qctrl.type == V4L2_CTRL_TYPE_MENU) menu_items = v4l2_ctrl_get_menu(qctrl.id); return v4l2_ctrl_check(vctrl, &qctrl, menu_items); }
/* Fill in a struct v4l2_querymenu based on the specified array of valid menu items (terminated by V4L2_CTRL_MENU_IDS_END). Use this if there are 'holes' in the list of valid menu items. */ int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *ids) { const char * const *menu_items = v4l2_ctrl_get_menu(qmenu->id); qmenu->reserved = 0; if (menu_items == NULL || ids == NULL) return -EINVAL; while (*ids != V4L2_CTRL_MENU_IDS_END) { if (*ids++ == qmenu->index) { strlcpy(qmenu->name, menu_items[qmenu->index], sizeof(qmenu->name)); return 0; } } return -EINVAL; }
/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and the menu. The qctrl pointer may be NULL, in which case it is ignored. If menu_items is NULL, then the menu items are retrieved using v4l2_ctrl_get_menu. */ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qctrl, const char * const *menu_items) { int i; qmenu->reserved = 0; if (menu_items == NULL) menu_items = v4l2_ctrl_get_menu(qmenu->id); if (menu_items == NULL || (qctrl && (qmenu->index < qctrl->minimum || qmenu->index > qctrl->maximum))) return -EINVAL; for (i = 0; i < qmenu->index && menu_items[i]; i++) ; if (menu_items[i] == NULL || menu_items[i][0] == '\0') return -EINVAL; strlcpy(qmenu->name, menu_items[qmenu->index], sizeof(qmenu->name)); return 0; }
static void format_ctx(struct seq_file *s, struct hva_ctx *ctx) { struct hva_streaminfo *stream = &ctx->streaminfo; struct hva_frameinfo *frame = &ctx->frameinfo; struct hva_controls *ctrls = &ctx->ctrls; struct hva_ctx_dbg *dbg = &ctx->dbg; u32 bitrate_mode, aspect, entropy, vui_sar, sei_fp; seq_printf(s, "|-%s\n |\n", ctx->name); seq_printf(s, " |-[%sframe info]\n", ctx->flags & HVA_FLAG_FRAMEINFO ? "" : "default "); seq_printf(s, " | |- pixel format=%4.4s\n" " | |- wxh=%dx%d\n" " | |- wxh (w/ encoder alignment constraint)=%dx%d\n" " |\n", (char *)&frame->pixelformat, frame->width, frame->height, frame->aligned_width, frame->aligned_height); seq_printf(s, " |-[%sstream info]\n", ctx->flags & HVA_FLAG_STREAMINFO ? "" : "default "); seq_printf(s, " | |- stream format=%4.4s\n" " | |- wxh=%dx%d\n" " | |- %s\n" " | |- %s\n" " |\n", (char *)&stream->streamformat, stream->width, stream->height, stream->profile, stream->level); bitrate_mode = V4L2_CID_MPEG_VIDEO_BITRATE_MODE; aspect = V4L2_CID_MPEG_VIDEO_ASPECT; seq_puts(s, " |-[parameters]\n"); seq_printf(s, " | |- %s\n" " | |- bitrate=%d bps\n" " | |- GOP size=%d\n" " | |- video aspect=%s\n" " | |- framerate=%d/%d\n", v4l2_ctrl_get_menu(bitrate_mode)[ctrls->bitrate_mode], ctrls->bitrate, ctrls->gop_size, v4l2_ctrl_get_menu(aspect)[ctrls->aspect], ctrls->time_per_frame.denominator, ctrls->time_per_frame.numerator); entropy = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; vui_sar = V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC; sei_fp = V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE; if (stream->streamformat == V4L2_PIX_FMT_H264) { seq_printf(s, " | |- %s entropy mode\n" " | |- CPB size=%d kB\n" " | |- DCT8x8 enable=%s\n" " | |- qpmin=%d\n" " | |- qpmax=%d\n" " | |- PAR enable=%s\n" " | |- PAR id=%s\n" " | |- SEI frame packing enable=%s\n" " | |- SEI frame packing type=%s\n", v4l2_ctrl_get_menu(entropy)[ctrls->entropy_mode], ctrls->cpb_size, ctrls->dct8x8 ? "true" : "false", ctrls->qpmin, ctrls->qpmax, ctrls->vui_sar ? "true" : "false", v4l2_ctrl_get_menu(vui_sar)[ctrls->vui_sar_idc], ctrls->sei_fp ? "true" : "false", v4l2_ctrl_get_menu(sei_fp)[ctrls->sei_fp_type]); } if (ctx->sys_errors || ctx->encode_errors || ctx->frame_errors) { seq_puts(s, " |\n |-[errors]\n"); seq_printf(s, " | |- system=%d\n" " | |- encoding=%d\n" " | |- frame=%d\n", ctx->sys_errors, ctx->encode_errors, ctx->frame_errors); } seq_puts(s, " |\n |-[performances]\n"); seq_printf(s, " | |- frames encoded=%d\n" " | |- avg HW processing duration (0.1ms)=%d [min=%d, max=%d]\n" " | |- avg encoding period (0.1ms)=%d [min=%d, max=%d]\n" " | |- avg fps (0.1Hz)=%d\n" " | |- max reachable fps (0.1Hz)=%d\n" " | |- avg bitrate (kbps)=%d [min=%d, max=%d]\n" " | |- last bitrate (kbps)=%d\n", dbg->cnt_duration, dbg->avg_duration, dbg->min_duration, dbg->max_duration, dbg->avg_period, dbg->min_period, dbg->max_period, dbg->avg_fps, dbg->max_fps, dbg->avg_bitrate, dbg->min_bitrate, dbg->max_bitrate, dbg->last_bitrate); }
static int hva_s_ctrl(struct v4l2_ctrl *ctrl) { struct hva_ctx *ctx = container_of(ctrl->handler, struct hva_ctx, ctrl_handler); struct device *dev = ctx_to_dev(ctx); dev_dbg(dev, "%s S_CTRL: id = %d, val = %d\n", ctx->name, ctrl->id, ctrl->val); switch (ctrl->id) { case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: ctx->ctrls.bitrate_mode = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_GOP_SIZE: ctx->ctrls.gop_size = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_BITRATE: ctx->ctrls.bitrate = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_ASPECT: ctx->ctrls.aspect = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_PROFILE: ctx->ctrls.profile = ctrl->val; if (ctx->flags & HVA_FLAG_STREAMINFO) snprintf(ctx->streaminfo.profile, sizeof(ctx->streaminfo.profile), "%s profile", v4l2_ctrl_get_menu(ctrl->id)[ctrl->val]); break; case V4L2_CID_MPEG_VIDEO_H264_LEVEL: ctx->ctrls.level = ctrl->val; if (ctx->flags & HVA_FLAG_STREAMINFO) snprintf(ctx->streaminfo.level, sizeof(ctx->streaminfo.level), "level %s", v4l2_ctrl_get_menu(ctrl->id)[ctrl->val]); break; case V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE: ctx->ctrls.entropy_mode = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE: ctx->ctrls.cpb_size = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM: ctx->ctrls.dct8x8 = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_MIN_QP: ctx->ctrls.qpmin = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_MAX_QP: ctx->ctrls.qpmax = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE: ctx->ctrls.vui_sar = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC: ctx->ctrls.vui_sar_idc = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING: ctx->ctrls.sei_fp = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE: ctx->ctrls.sei_fp_type = ctrl->val; break; default: dev_dbg(dev, "%s S_CTRL: invalid control (id = %d)\n", ctx->name, ctrl->id); return -EINVAL; } return 0; }