@@ -1662,6 +1662,8 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
return ret;
v4l_sanitize_format(p);
+ trace_v4l2_ioctl_s_fmt(file, fh, p);
+
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
if (unlikely(!ops->vidioc_s_fmt_vid_cap))
@@ -10,3 +10,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_buf_done);
EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_buf_queue);
EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_dqbuf);
EXPORT_TRACEPOINT_SYMBOL_GPL(vb2_v4l2_qbuf);
+EXPORT_TRACEPOINT_SYMBOL_GPL(v4l2_ioctl_s_fmt);
@@ -6,8 +6,10 @@
#define _TRACE_V4L2_H
#include <linux/tracepoint.h>
+#include <linux/videodev2.h>
#include <media/videobuf2-v4l2.h>
#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
/* Enums require being exported to userspace, for user tool parsing */
#undef EM
@@ -264,6 +266,136 @@ DEFINE_EVENT(vb2_v4l2_event_class, vb2_v4l2_qbuf,
TP_ARGS(q, vb)
);
+#ifdef CREATE_TRACE_POINTS
+#define __trace_array_name(a, arr, num) (((unsigned)(a)) < num ? arr[a] : "unknown")
+static inline void __trace_sprint_v4l2_format(char *str, size_t size, struct v4l2_format *p)
+{
+ const struct v4l2_pix_format *pix;
+ const struct v4l2_pix_format_mplane *mp;
+ const struct v4l2_vbi_format *vbi;
+ const struct v4l2_sliced_vbi_format *sliced;
+ const struct v4l2_window *win;
+ const struct v4l2_sdr_format *sdr;
+ const struct v4l2_meta_format *meta;
+
+ switch (p->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ pix = &p->fmt.pix;
+ snprintf(str, size, "width=%u, height=%u, pixelformat=%c%c%c%c, "
+ "field=%s, bytesperline=%u, sizeimage=%u, "
+ "colorspace=%d, flags=0x%x, ycbcr_enc=%u, "
+ "quantization=%u, xfer_func=%u",
+ pix->width, pix->height,
+ (pix->pixelformat & 0xff),
+ (pix->pixelformat >> 8) & 0xff,
+ (pix->pixelformat >> 16) & 0xff,
+ (pix->pixelformat >> 24) & 0xff,
+ __trace_array_name(pix->field, v4l2_field_names, V4L2_FIELD_NUM),
+ pix->bytesperline, pix->sizeimage,
+ pix->colorspace, pix->flags, pix->ycbcr_enc,
+ pix->quantization, pix->xfer_func);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+ mp = &p->fmt.pix_mp;
+ snprintf(str, size, "width=%u, height=%u, pixelformat=%c%c%c%c, "
+ "field=%s, num_planes=%u, "
+ "colorspace=%d, flags=0x%x, ycbcr_enc=%u, "
+ "quantization=%u, xfer_func=%u}",
+ mp->width, mp->height,
+ (mp->pixelformat & 0xff),
+ (mp->pixelformat >> 8) & 0xff,
+ (mp->pixelformat >> 16) & 0xff,
+ (mp->pixelformat >> 24) & 0xff,
+ __trace_array_name(mp->field, v4l2_field_names, V4L2_FIELD_NUM),
+ mp->num_planes,
+ mp->colorspace, mp->flags, mp->ycbcr_enc,
+ mp->quantization, mp->xfer_func);
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
+ win = &p->fmt.win;
+ /* Note: we can't print the clip list here since the clips
+ * pointer is a userspace pointer, not a kernelspace
+ * pointer. */
+ snprintf(str, size, "wxh=%dx%d, x,y=%d,%d, field=%s, "
+ "chromakey=0x%08x, clipcount=%u, clips=%p, "
+ "bitmap=%p, global_alpha=0x%02x",
+ win->w.width, win->w.height, win->w.left, win->w.top,
+ __trace_array_name(win->field, v4l2_field_names, V4L2_FIELD_NUM),
+ win->chromakey, win->clipcount, win->clips,
+ win->bitmap, win->global_alpha);
+ break;
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ vbi = &p->fmt.vbi;
+ pr_cont("sampling_rate=%u, offset=%u, samples_per_line=%u, "
+ "sample_format=%c%c%c%c, start=%u,%u, count=%u,%u",
+ vbi->sampling_rate, vbi->offset,
+ vbi->samples_per_line,
+ (vbi->sample_format & 0xff),
+ (vbi->sample_format >> 8) & 0xff,
+ (vbi->sample_format >> 16) & 0xff,
+ (vbi->sample_format >> 24) & 0xff,
+ vbi->start[0], vbi->start[1],
+ vbi->count[0], vbi->count[1]);
+ break;
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ sliced = &p->fmt.sliced;
+ snprintf(str, size, "service_set=0x%08x, io_size=%d",
+ sliced->service_set, sliced->io_size);
+ break;
+ case V4L2_BUF_TYPE_SDR_CAPTURE:
+ case V4L2_BUF_TYPE_SDR_OUTPUT:
+ sdr = &p->fmt.sdr;
+ snprintf(str, size, "pixelformat=%c%c%c%c",
+ (sdr->pixelformat >> 0) & 0xff,
+ (sdr->pixelformat >> 8) & 0xff,
+ (sdr->pixelformat >> 16) & 0xff,
+ (sdr->pixelformat >> 24) & 0xff);
+ break;
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ case V4L2_BUF_TYPE_META_OUTPUT:
+ meta = &p->fmt.meta;
+ snprintf(str, size, "dataformat=%c%c%c%c, buffersize=%u",
+ (meta->dataformat >> 0) & 0xff,
+ (meta->dataformat >> 8) & 0xff,
+ (meta->dataformat >> 16) & 0xff,
+ (meta->dataformat >> 24) & 0xff,
+ meta->buffersize);
+ break;
+ }
+}
+#endif
+
+#define V4L2_FMT_MAX 256
+
+/* v4l2-ioctl trace events */
+TRACE_EVENT(v4l2_ioctl_s_fmt,
+ TP_PROTO(struct file *file, struct v4l2_fh *fh, struct v4l2_format *fmt),
+ TP_ARGS(file, fh, fmt),
+
+ TP_STRUCT__entry(
+ __field(int, minor)
+ __field(struct v4l2_fh *, fh)
+ __field(u32, type)
+ __dynamic_array(char, details, V4L2_FMT_MAX)
+ ),
+
+ TP_fast_assign(
+ __entry->minor = video_devdata(file)->minor;
+ __entry->fh = fh;
+ __entry->type = fmt->type;
+ __trace_sprint_v4l2_format(__get_str(details), V4L2_FMT_MAX, fmt);
+ ),
+
+ TP_printk("minor = %d, fh = %p, type = %s, %s",
+ __entry->minor, __entry->fh,
+ show_type(__entry->type), __get_str(details))
+);
+
#endif /* if !defined(_TRACE_V4L2_H) || defined(TRACE_HEADER_MULTI_READ) */
/* This part must be outside protection */
@@ -105,6 +105,7 @@ enum v4l2_field {
V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field
first and the bottom field is
transmitted first */
+ V4L2_FIELD_NUM
};
#define V4L2_FIELD_HAS_TOP(field) \
((field) == V4L2_FIELD_TOP ||\