500 lines
15 KiB
C
500 lines
15 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Contains the virtual decoder logic. The functions here control the
|
|
* tracing/TPG on a per-frame basis
|
|
*/
|
|
|
|
#include "visl.h"
|
|
#include "visl-debugfs.h"
|
|
#include "visl-dec.h"
|
|
#include "visl-trace-fwht.h"
|
|
#include "visl-trace-mpeg2.h"
|
|
#include "visl-trace-vp8.h"
|
|
#include "visl-trace-vp9.h"
|
|
#include "visl-trace-h264.h"
|
|
#include "visl-trace-hevc.h"
|
|
|
|
#include <linux/delay.h>
|
|
#include <linux/workqueue.h>
|
|
#include <media/v4l2-mem2mem.h>
|
|
#include <media/tpg/v4l2-tpg.h>
|
|
|
|
static void *plane_vaddr(struct tpg_data *tpg, struct vb2_buffer *buf,
|
|
u32 p, u32 bpl[TPG_MAX_PLANES], u32 h)
|
|
{
|
|
u32 i;
|
|
void *vbuf;
|
|
|
|
if (p == 0 || tpg_g_buffers(tpg) > 1)
|
|
return vb2_plane_vaddr(buf, p);
|
|
vbuf = vb2_plane_vaddr(buf, 0);
|
|
for (i = 0; i < p; i++)
|
|
vbuf += bpl[i] * h / tpg->vdownsampling[i];
|
|
return vbuf;
|
|
}
|
|
|
|
static void visl_get_ref_frames(struct visl_ctx *ctx, u8 *buf,
|
|
__kernel_size_t buflen, struct visl_run *run)
|
|
{
|
|
struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
|
|
char header[] = "Reference frames:\n";
|
|
u32 i;
|
|
u32 len;
|
|
|
|
len = scnprintf(buf, buflen, header);
|
|
buf += len;
|
|
buflen -= len;
|
|
|
|
switch (ctx->current_codec) {
|
|
case VISL_CODEC_NONE:
|
|
break;
|
|
|
|
case VISL_CODEC_FWHT: {
|
|
struct vb2_buffer *vb2_buf;
|
|
|
|
vb2_buf = vb2_find_buffer(cap_q, run->fwht.params->backward_ref_ts);
|
|
|
|
scnprintf(buf, buflen, "backwards_ref_ts: %lld, vb2_idx: %d",
|
|
run->fwht.params->backward_ref_ts,
|
|
vb2_buf ? vb2_buf->index : -1);
|
|
break;
|
|
}
|
|
|
|
case VISL_CODEC_MPEG2: {
|
|
struct vb2_buffer *b_ref;
|
|
struct vb2_buffer *f_ref;
|
|
|
|
b_ref = vb2_find_buffer(cap_q, run->mpeg2.pic->backward_ref_ts);
|
|
f_ref = vb2_find_buffer(cap_q, run->mpeg2.pic->forward_ref_ts);
|
|
|
|
scnprintf(buf, buflen,
|
|
"backward_ref_ts: %llu, vb2_idx: %d\n"
|
|
"forward_ref_ts: %llu, vb2_idx: %d\n",
|
|
run->mpeg2.pic->backward_ref_ts,
|
|
b_ref ? b_ref->index : -1,
|
|
run->mpeg2.pic->forward_ref_ts,
|
|
f_ref ? f_ref->index : -1);
|
|
break;
|
|
}
|
|
|
|
case VISL_CODEC_VP8: {
|
|
struct vb2_buffer *last;
|
|
struct vb2_buffer *golden;
|
|
struct vb2_buffer *alt;
|
|
|
|
last = vb2_find_buffer(cap_q, run->vp8.frame->last_frame_ts);
|
|
golden = vb2_find_buffer(cap_q, run->vp8.frame->golden_frame_ts);
|
|
alt = vb2_find_buffer(cap_q, run->vp8.frame->alt_frame_ts);
|
|
|
|
scnprintf(buf, buflen,
|
|
"last_ref_ts: %llu, vb2_idx: %d\n"
|
|
"golden_ref_ts: %llu, vb2_idx: %d\n"
|
|
"alt_ref_ts: %llu, vb2_idx: %d\n",
|
|
run->vp8.frame->last_frame_ts,
|
|
last ? last->index : -1,
|
|
run->vp8.frame->golden_frame_ts,
|
|
golden ? golden->index : -1,
|
|
run->vp8.frame->alt_frame_ts,
|
|
alt ? alt->index : -1);
|
|
break;
|
|
}
|
|
|
|
case VISL_CODEC_VP9: {
|
|
struct vb2_buffer *last;
|
|
struct vb2_buffer *golden;
|
|
struct vb2_buffer *alt;
|
|
|
|
last = vb2_find_buffer(cap_q, run->vp9.frame->last_frame_ts);
|
|
golden = vb2_find_buffer(cap_q, run->vp9.frame->golden_frame_ts);
|
|
alt = vb2_find_buffer(cap_q, run->vp9.frame->alt_frame_ts);
|
|
|
|
scnprintf(buf, buflen,
|
|
"last_ref_ts: %llu, vb2_idx: %d\n"
|
|
"golden_ref_ts: %llu, vb2_idx: %d\n"
|
|
"alt_ref_ts: %llu, vb2_idx: %d\n",
|
|
run->vp9.frame->last_frame_ts,
|
|
last ? last->index : -1,
|
|
run->vp9.frame->golden_frame_ts,
|
|
golden ? golden->index : -1,
|
|
run->vp9.frame->alt_frame_ts,
|
|
alt ? alt->index : -1);
|
|
break;
|
|
}
|
|
|
|
case VISL_CODEC_H264: {
|
|
char entry[] = "dpb[%d]:%u, vb2_index: %d\n";
|
|
struct vb2_buffer *vb2_buf;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(run->h264.dpram->dpb); i++) {
|
|
vb2_buf = vb2_find_buffer(cap_q, run->h264.dpram->dpb[i].reference_ts);
|
|
len = scnprintf(buf, buflen, entry, i,
|
|
run->h264.dpram->dpb[i].reference_ts,
|
|
vb2_buf ? vb2_buf->index : -1);
|
|
buf += len;
|
|
buflen -= len;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case VISL_CODEC_HEVC: {
|
|
char entry[] = "dpb[%d]:%u, vb2_index: %d\n";
|
|
struct vb2_buffer *vb2_buf;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(run->hevc.dpram->dpb); i++) {
|
|
vb2_buf = vb2_find_buffer(cap_q, run->hevc.dpram->dpb[i].timestamp);
|
|
len = scnprintf(buf, buflen, entry, i,
|
|
run->hevc.dpram->dpb[i].timestamp,
|
|
vb2_buf ? vb2_buf->index : -1);
|
|
buf += len;
|
|
buflen -= len;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static char *visl_get_vb2_state(enum vb2_buffer_state state)
|
|
{
|
|
switch (state) {
|
|
case VB2_BUF_STATE_DEQUEUED:
|
|
return "Dequeued";
|
|
case VB2_BUF_STATE_IN_REQUEST:
|
|
return "In request";
|
|
case VB2_BUF_STATE_PREPARING:
|
|
return "Preparing";
|
|
case VB2_BUF_STATE_QUEUED:
|
|
return "Queued";
|
|
case VB2_BUF_STATE_ACTIVE:
|
|
return "Active";
|
|
case VB2_BUF_STATE_DONE:
|
|
return "Done";
|
|
case VB2_BUF_STATE_ERROR:
|
|
return "Error";
|
|
default:
|
|
return "";
|
|
}
|
|
}
|
|
|
|
static int visl_fill_bytesused(struct vb2_v4l2_buffer *v4l2_vb2_buf, char *buf, size_t bufsz)
|
|
{
|
|
int len = 0;
|
|
u32 i;
|
|
|
|
for (i = 0; i < v4l2_vb2_buf->vb2_buf.num_planes; i++)
|
|
len += scnprintf(buf, bufsz,
|
|
"bytesused[%u]: %u length[%u]: %u data_offset[%u]: %u",
|
|
i, v4l2_vb2_buf->planes[i].bytesused,
|
|
i, v4l2_vb2_buf->planes[i].length,
|
|
i, v4l2_vb2_buf->planes[i].data_offset);
|
|
|
|
return len;
|
|
}
|
|
|
|
static void visl_tpg_fill_sequence(struct visl_ctx *ctx,
|
|
struct visl_run *run, char buf[], size_t bufsz)
|
|
{
|
|
u32 stream_ms;
|
|
|
|
stream_ms = jiffies_to_msecs(get_jiffies_64() - ctx->capture_streamon_jiffies);
|
|
|
|
scnprintf(buf, bufsz,
|
|
"stream time: %02d:%02d:%02d:%03d sequence:%u timestamp:%lld field:%s",
|
|
(stream_ms / (60 * 60 * 1000)) % 24,
|
|
(stream_ms / (60 * 1000)) % 60,
|
|
(stream_ms / 1000) % 60,
|
|
stream_ms % 1000,
|
|
run->dst->sequence,
|
|
run->dst->vb2_buf.timestamp,
|
|
(run->dst->field == V4L2_FIELD_ALTERNATE) ?
|
|
(run->dst->field == V4L2_FIELD_TOP ?
|
|
" top" : " bottom") : "none");
|
|
}
|
|
|
|
static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run)
|
|
{
|
|
u8 *basep[TPG_MAX_PLANES][2];
|
|
char *buf = ctx->tpg_str_buf;
|
|
char *tmp = buf;
|
|
char *line_str;
|
|
u32 line = 1;
|
|
const u32 line_height = 16;
|
|
u32 len;
|
|
struct vb2_queue *out_q = &ctx->fh.m2m_ctx->out_q_ctx.q;
|
|
struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
|
|
struct v4l2_pix_format_mplane *coded_fmt = &ctx->coded_fmt.fmt.pix_mp;
|
|
struct v4l2_pix_format_mplane *decoded_fmt = &ctx->decoded_fmt.fmt.pix_mp;
|
|
u32 p;
|
|
u32 i;
|
|
|
|
for (p = 0; p < tpg_g_planes(&ctx->tpg); p++) {
|
|
void *vbuf = plane_vaddr(&ctx->tpg,
|
|
&run->dst->vb2_buf, p,
|
|
ctx->tpg.bytesperline,
|
|
ctx->tpg.buf_height);
|
|
|
|
tpg_calc_text_basep(&ctx->tpg, basep, p, vbuf);
|
|
tpg_fill_plane_buffer(&ctx->tpg, 0, p, vbuf);
|
|
}
|
|
|
|
visl_tpg_fill_sequence(ctx, run, buf, TPG_STR_BUF_SZ);
|
|
tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "");
|
|
line++;
|
|
|
|
visl_get_ref_frames(ctx, buf, TPG_STR_BUF_SZ, run);
|
|
|
|
while ((line_str = strsep(&tmp, "\n")) && strlen(line_str)) {
|
|
tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, line_str);
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", line_str);
|
|
}
|
|
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "");
|
|
line++;
|
|
|
|
scnprintf(buf,
|
|
TPG_STR_BUF_SZ,
|
|
"OUTPUT pixelformat: %c%c%c%c, resolution: %dx%d, num_planes: %d",
|
|
coded_fmt->pixelformat,
|
|
(coded_fmt->pixelformat >> 8) & 0xff,
|
|
(coded_fmt->pixelformat >> 16) & 0xff,
|
|
(coded_fmt->pixelformat >> 24) & 0xff,
|
|
coded_fmt->width,
|
|
coded_fmt->height,
|
|
coded_fmt->num_planes);
|
|
|
|
tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
|
|
|
|
for (i = 0; i < coded_fmt->num_planes; i++) {
|
|
scnprintf(buf,
|
|
TPG_STR_BUF_SZ,
|
|
"plane[%d]: bytesperline: %d, sizeimage: %d",
|
|
i,
|
|
coded_fmt->plane_fmt[i].bytesperline,
|
|
coded_fmt->plane_fmt[i].sizeimage);
|
|
|
|
tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
|
|
}
|
|
|
|
line++;
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "");
|
|
scnprintf(buf, TPG_STR_BUF_SZ, "Output queue status:");
|
|
tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
|
|
|
|
len = 0;
|
|
for (i = 0; i < out_q->num_buffers; i++) {
|
|
char entry[] = "index: %u, state: %s, request_fd: %d, ";
|
|
u32 old_len = len;
|
|
char *q_status = visl_get_vb2_state(out_q->bufs[i]->state);
|
|
|
|
len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len,
|
|
entry, i, q_status,
|
|
to_vb2_v4l2_buffer(out_q->bufs[i])->request_fd);
|
|
|
|
len += visl_fill_bytesused(to_vb2_v4l2_buffer(out_q->bufs[i]),
|
|
&buf[len],
|
|
TPG_STR_BUF_SZ - len);
|
|
|
|
tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]);
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]);
|
|
}
|
|
|
|
line++;
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "");
|
|
|
|
scnprintf(buf,
|
|
TPG_STR_BUF_SZ,
|
|
"CAPTURE pixelformat: %c%c%c%c, resolution: %dx%d, num_planes: %d",
|
|
decoded_fmt->pixelformat,
|
|
(decoded_fmt->pixelformat >> 8) & 0xff,
|
|
(decoded_fmt->pixelformat >> 16) & 0xff,
|
|
(decoded_fmt->pixelformat >> 24) & 0xff,
|
|
decoded_fmt->width,
|
|
decoded_fmt->height,
|
|
decoded_fmt->num_planes);
|
|
|
|
tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
|
|
|
|
for (i = 0; i < decoded_fmt->num_planes; i++) {
|
|
scnprintf(buf,
|
|
TPG_STR_BUF_SZ,
|
|
"plane[%d]: bytesperline: %d, sizeimage: %d",
|
|
i,
|
|
decoded_fmt->plane_fmt[i].bytesperline,
|
|
decoded_fmt->plane_fmt[i].sizeimage);
|
|
|
|
tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
|
|
}
|
|
|
|
line++;
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "");
|
|
scnprintf(buf, TPG_STR_BUF_SZ, "Capture queue status:");
|
|
tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
|
|
|
|
len = 0;
|
|
for (i = 0; i < cap_q->num_buffers; i++) {
|
|
u32 old_len = len;
|
|
char *q_status = visl_get_vb2_state(cap_q->bufs[i]->state);
|
|
|
|
len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len,
|
|
"index: %u, status: %s, timestamp: %llu, is_held: %d",
|
|
cap_q->bufs[i]->index, q_status,
|
|
cap_q->bufs[i]->timestamp,
|
|
to_vb2_v4l2_buffer(cap_q->bufs[i])->is_held);
|
|
|
|
tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]);
|
|
frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]);
|
|
}
|
|
}
|
|
|
|
static void visl_trace_ctrls(struct visl_ctx *ctx, struct visl_run *run)
|
|
{
|
|
int i;
|
|
|
|
switch (ctx->current_codec) {
|
|
default:
|
|
case VISL_CODEC_NONE:
|
|
break;
|
|
case VISL_CODEC_FWHT:
|
|
trace_v4l2_ctrl_fwht_params(run->fwht.params);
|
|
break;
|
|
case VISL_CODEC_MPEG2:
|
|
trace_v4l2_ctrl_mpeg2_sequence(run->mpeg2.seq);
|
|
trace_v4l2_ctrl_mpeg2_picture(run->mpeg2.pic);
|
|
trace_v4l2_ctrl_mpeg2_quantisation(run->mpeg2.quant);
|
|
break;
|
|
case VISL_CODEC_VP8:
|
|
trace_v4l2_ctrl_vp8_frame(run->vp8.frame);
|
|
trace_v4l2_ctrl_vp8_entropy(run->vp8.frame);
|
|
break;
|
|
case VISL_CODEC_VP9:
|
|
trace_v4l2_ctrl_vp9_frame(run->vp9.frame);
|
|
trace_v4l2_ctrl_vp9_compressed_hdr(run->vp9.probs);
|
|
trace_v4l2_ctrl_vp9_compressed_coeff(run->vp9.probs);
|
|
trace_v4l2_vp9_mv_probs(&run->vp9.probs->mv);
|
|
break;
|
|
case VISL_CODEC_H264:
|
|
trace_v4l2_ctrl_h264_sps(run->h264.sps);
|
|
trace_v4l2_ctrl_h264_pps(run->h264.pps);
|
|
trace_v4l2_ctrl_h264_scaling_matrix(run->h264.sm);
|
|
trace_v4l2_ctrl_h264_slice_params(run->h264.spram);
|
|
|
|
for (i = 0; i < ARRAY_SIZE(run->h264.spram->ref_pic_list0); i++)
|
|
trace_v4l2_h264_ref_pic_list0(&run->h264.spram->ref_pic_list0[i], i);
|
|
for (i = 0; i < ARRAY_SIZE(run->h264.spram->ref_pic_list0); i++)
|
|
trace_v4l2_h264_ref_pic_list1(&run->h264.spram->ref_pic_list1[i], i);
|
|
|
|
trace_v4l2_ctrl_h264_decode_params(run->h264.dpram);
|
|
|
|
for (i = 0; i < ARRAY_SIZE(run->h264.dpram->dpb); i++)
|
|
trace_v4l2_h264_dpb_entry(&run->h264.dpram->dpb[i], i);
|
|
|
|
trace_v4l2_ctrl_h264_pred_weights(run->h264.pwht);
|
|
break;
|
|
case VISL_CODEC_HEVC:
|
|
trace_v4l2_ctrl_hevc_sps(run->hevc.sps);
|
|
trace_v4l2_ctrl_hevc_pps(run->hevc.pps);
|
|
trace_v4l2_ctrl_hevc_slice_params(run->hevc.spram);
|
|
trace_v4l2_ctrl_hevc_scaling_matrix(run->hevc.sm);
|
|
trace_v4l2_ctrl_hevc_decode_params(run->hevc.dpram);
|
|
|
|
for (i = 0; i < ARRAY_SIZE(run->hevc.dpram->dpb); i++)
|
|
trace_v4l2_hevc_dpb_entry(&run->hevc.dpram->dpb[i]);
|
|
|
|
trace_v4l2_hevc_pred_weight_table(&run->hevc.spram->pred_weight_table);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void visl_device_run(void *priv)
|
|
{
|
|
struct visl_ctx *ctx = priv;
|
|
struct visl_run run = {};
|
|
struct media_request *src_req;
|
|
|
|
run.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
|
|
run.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
|
|
|
|
/* Apply request(s) controls if needed. */
|
|
src_req = run.src->vb2_buf.req_obj.req;
|
|
|
|
if (src_req)
|
|
v4l2_ctrl_request_setup(src_req, &ctx->hdl);
|
|
|
|
v4l2_m2m_buf_copy_metadata(run.src, run.dst, true);
|
|
run.dst->sequence = ctx->q_data[V4L2_M2M_DST].sequence++;
|
|
run.src->sequence = ctx->q_data[V4L2_M2M_SRC].sequence++;
|
|
run.dst->field = ctx->decoded_fmt.fmt.pix.field;
|
|
|
|
switch (ctx->current_codec) {
|
|
default:
|
|
case VISL_CODEC_NONE:
|
|
break;
|
|
case VISL_CODEC_FWHT:
|
|
run.fwht.params = visl_find_control_data(ctx, V4L2_CID_STATELESS_FWHT_PARAMS);
|
|
break;
|
|
case VISL_CODEC_MPEG2:
|
|
run.mpeg2.seq = visl_find_control_data(ctx, V4L2_CID_STATELESS_MPEG2_SEQUENCE);
|
|
run.mpeg2.pic = visl_find_control_data(ctx, V4L2_CID_STATELESS_MPEG2_PICTURE);
|
|
run.mpeg2.quant = visl_find_control_data(ctx,
|
|
V4L2_CID_STATELESS_MPEG2_QUANTISATION);
|
|
break;
|
|
case VISL_CODEC_VP8:
|
|
run.vp8.frame = visl_find_control_data(ctx, V4L2_CID_STATELESS_VP8_FRAME);
|
|
break;
|
|
case VISL_CODEC_VP9:
|
|
run.vp9.frame = visl_find_control_data(ctx, V4L2_CID_STATELESS_VP9_FRAME);
|
|
run.vp9.probs = visl_find_control_data(ctx, V4L2_CID_STATELESS_VP9_COMPRESSED_HDR);
|
|
break;
|
|
case VISL_CODEC_H264:
|
|
run.h264.sps = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_SPS);
|
|
run.h264.pps = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_PPS);
|
|
run.h264.sm = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
|
|
run.h264.spram = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_SLICE_PARAMS);
|
|
run.h264.dpram = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
|
|
run.h264.pwht = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_PRED_WEIGHTS);
|
|
break;
|
|
case VISL_CODEC_HEVC:
|
|
run.hevc.sps = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SPS);
|
|
run.hevc.pps = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_PPS);
|
|
run.hevc.spram = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SLICE_PARAMS);
|
|
run.hevc.sm = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SCALING_MATRIX);
|
|
run.hevc.dpram = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_DECODE_PARAMS);
|
|
break;
|
|
}
|
|
|
|
frame_dprintk(ctx->dev, run.dst->sequence,
|
|
"Got OUTPUT buffer sequence %d, timestamp %llu\n",
|
|
run.src->sequence, run.src->vb2_buf.timestamp);
|
|
|
|
frame_dprintk(ctx->dev, run.dst->sequence,
|
|
"Got CAPTURE buffer sequence %d, timestamp %llu\n",
|
|
run.dst->sequence, run.dst->vb2_buf.timestamp);
|
|
|
|
visl_tpg_fill(ctx, &run);
|
|
visl_trace_ctrls(ctx, &run);
|
|
|
|
if (bitstream_trace_frame_start > -1 &&
|
|
run.dst->sequence >= bitstream_trace_frame_start &&
|
|
run.dst->sequence < bitstream_trace_frame_start + bitstream_trace_nframes)
|
|
visl_trace_bitstream(ctx, &run);
|
|
|
|
/* Complete request(s) controls if needed. */
|
|
if (src_req)
|
|
v4l2_ctrl_request_complete(src_req, &ctx->hdl);
|
|
|
|
if (visl_transtime_ms)
|
|
usleep_range(visl_transtime_ms * 1000, 2 * visl_transtime_ms * 1000);
|
|
|
|
v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev,
|
|
ctx->fh.m2m_ctx, VB2_BUF_STATE_DONE);
|
|
}
|