1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Contains the virtual decoder logic. The functions here control the
4 * tracing/TPG on a per-frame basis
5 */
6
7 #include "visl.h"
8 #include "visl-debugfs.h"
9 #include "visl-dec.h"
10 #include "visl-trace-fwht.h"
11 #include "visl-trace-mpeg2.h"
12 #include "visl-trace-vp8.h"
13 #include "visl-trace-vp9.h"
14 #include "visl-trace-h264.h"
15 #include "visl-trace-hevc.h"
16
17 #include <linux/delay.h>
18 #include <linux/workqueue.h>
19 #include <media/v4l2-mem2mem.h>
20 #include <media/tpg/v4l2-tpg.h>
21
plane_vaddr(struct tpg_data * tpg,struct vb2_buffer * buf,u32 p,u32 bpl[TPG_MAX_PLANES],u32 h)22 static void *plane_vaddr(struct tpg_data *tpg, struct vb2_buffer *buf,
23 u32 p, u32 bpl[TPG_MAX_PLANES], u32 h)
24 {
25 u32 i;
26 void *vbuf;
27
28 if (p == 0 || tpg_g_buffers(tpg) > 1)
29 return vb2_plane_vaddr(buf, p);
30 vbuf = vb2_plane_vaddr(buf, 0);
31 for (i = 0; i < p; i++)
32 vbuf += bpl[i] * h / tpg->vdownsampling[i];
33 return vbuf;
34 }
35
visl_get_ref_frames(struct visl_ctx * ctx,u8 * buf,__kernel_size_t buflen,struct visl_run * run)36 static void visl_get_ref_frames(struct visl_ctx *ctx, u8 *buf,
37 __kernel_size_t buflen, struct visl_run *run)
38 {
39 struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
40 char header[] = "Reference frames:\n";
41 u32 i;
42 u32 len;
43
44 len = scnprintf(buf, buflen, header);
45 buf += len;
46 buflen -= len;
47
48 switch (ctx->current_codec) {
49 case VISL_CODEC_NONE:
50 break;
51
52 case VISL_CODEC_FWHT: {
53 struct vb2_buffer *vb2_buf;
54
55 vb2_buf = vb2_find_buffer(cap_q, run->fwht.params->backward_ref_ts);
56
57 scnprintf(buf, buflen, "backwards_ref_ts: %lld, vb2_idx: %d",
58 run->fwht.params->backward_ref_ts,
59 vb2_buf ? vb2_buf->index : -1);
60 break;
61 }
62
63 case VISL_CODEC_MPEG2: {
64 struct vb2_buffer *b_ref;
65 struct vb2_buffer *f_ref;
66
67 b_ref = vb2_find_buffer(cap_q, run->mpeg2.pic->backward_ref_ts);
68 f_ref = vb2_find_buffer(cap_q, run->mpeg2.pic->forward_ref_ts);
69
70 scnprintf(buf, buflen,
71 "backward_ref_ts: %llu, vb2_idx: %d\n"
72 "forward_ref_ts: %llu, vb2_idx: %d\n",
73 run->mpeg2.pic->backward_ref_ts,
74 b_ref ? b_ref->index : -1,
75 run->mpeg2.pic->forward_ref_ts,
76 f_ref ? f_ref->index : -1);
77 break;
78 }
79
80 case VISL_CODEC_VP8: {
81 struct vb2_buffer *last;
82 struct vb2_buffer *golden;
83 struct vb2_buffer *alt;
84
85 last = vb2_find_buffer(cap_q, run->vp8.frame->last_frame_ts);
86 golden = vb2_find_buffer(cap_q, run->vp8.frame->golden_frame_ts);
87 alt = vb2_find_buffer(cap_q, run->vp8.frame->alt_frame_ts);
88
89 scnprintf(buf, buflen,
90 "last_ref_ts: %llu, vb2_idx: %d\n"
91 "golden_ref_ts: %llu, vb2_idx: %d\n"
92 "alt_ref_ts: %llu, vb2_idx: %d\n",
93 run->vp8.frame->last_frame_ts,
94 last ? last->index : -1,
95 run->vp8.frame->golden_frame_ts,
96 golden ? golden->index : -1,
97 run->vp8.frame->alt_frame_ts,
98 alt ? alt->index : -1);
99 break;
100 }
101
102 case VISL_CODEC_VP9: {
103 struct vb2_buffer *last;
104 struct vb2_buffer *golden;
105 struct vb2_buffer *alt;
106
107 last = vb2_find_buffer(cap_q, run->vp9.frame->last_frame_ts);
108 golden = vb2_find_buffer(cap_q, run->vp9.frame->golden_frame_ts);
109 alt = vb2_find_buffer(cap_q, run->vp9.frame->alt_frame_ts);
110
111 scnprintf(buf, buflen,
112 "last_ref_ts: %llu, vb2_idx: %d\n"
113 "golden_ref_ts: %llu, vb2_idx: %d\n"
114 "alt_ref_ts: %llu, vb2_idx: %d\n",
115 run->vp9.frame->last_frame_ts,
116 last ? last->index : -1,
117 run->vp9.frame->golden_frame_ts,
118 golden ? golden->index : -1,
119 run->vp9.frame->alt_frame_ts,
120 alt ? alt->index : -1);
121 break;
122 }
123
124 case VISL_CODEC_H264: {
125 char entry[] = "dpb[%d]:%u, vb2_index: %d\n";
126 struct vb2_buffer *vb2_buf;
127
128 for (i = 0; i < ARRAY_SIZE(run->h264.dpram->dpb); i++) {
129 vb2_buf = vb2_find_buffer(cap_q, run->h264.dpram->dpb[i].reference_ts);
130 len = scnprintf(buf, buflen, entry, i,
131 run->h264.dpram->dpb[i].reference_ts,
132 vb2_buf ? vb2_buf->index : -1);
133 buf += len;
134 buflen -= len;
135 }
136
137 break;
138 }
139
140 case VISL_CODEC_HEVC: {
141 char entry[] = "dpb[%d]:%u, vb2_index: %d\n";
142 struct vb2_buffer *vb2_buf;
143
144 for (i = 0; i < ARRAY_SIZE(run->hevc.dpram->dpb); i++) {
145 vb2_buf = vb2_find_buffer(cap_q, run->hevc.dpram->dpb[i].timestamp);
146 len = scnprintf(buf, buflen, entry, i,
147 run->hevc.dpram->dpb[i].timestamp,
148 vb2_buf ? vb2_buf->index : -1);
149 buf += len;
150 buflen -= len;
151 }
152
153 break;
154 }
155 }
156 }
157
visl_get_vb2_state(enum vb2_buffer_state state)158 static char *visl_get_vb2_state(enum vb2_buffer_state state)
159 {
160 switch (state) {
161 case VB2_BUF_STATE_DEQUEUED:
162 return "Dequeued";
163 case VB2_BUF_STATE_IN_REQUEST:
164 return "In request";
165 case VB2_BUF_STATE_PREPARING:
166 return "Preparing";
167 case VB2_BUF_STATE_QUEUED:
168 return "Queued";
169 case VB2_BUF_STATE_ACTIVE:
170 return "Active";
171 case VB2_BUF_STATE_DONE:
172 return "Done";
173 case VB2_BUF_STATE_ERROR:
174 return "Error";
175 default:
176 return "";
177 }
178 }
179
visl_fill_bytesused(struct vb2_v4l2_buffer * v4l2_vb2_buf,char * buf,size_t bufsz)180 static int visl_fill_bytesused(struct vb2_v4l2_buffer *v4l2_vb2_buf, char *buf, size_t bufsz)
181 {
182 int len = 0;
183 u32 i;
184
185 for (i = 0; i < v4l2_vb2_buf->vb2_buf.num_planes; i++)
186 len += scnprintf(buf, bufsz,
187 "bytesused[%u]: %u length[%u]: %u data_offset[%u]: %u",
188 i, v4l2_vb2_buf->planes[i].bytesused,
189 i, v4l2_vb2_buf->planes[i].length,
190 i, v4l2_vb2_buf->planes[i].data_offset);
191
192 return len;
193 }
194
visl_tpg_fill_sequence(struct visl_ctx * ctx,struct visl_run * run,char buf[],size_t bufsz)195 static void visl_tpg_fill_sequence(struct visl_ctx *ctx,
196 struct visl_run *run, char buf[], size_t bufsz)
197 {
198 u32 stream_ms;
199
200 stream_ms = jiffies_to_msecs(get_jiffies_64() - ctx->capture_streamon_jiffies);
201
202 scnprintf(buf, bufsz,
203 "stream time: %02d:%02d:%02d:%03d sequence:%u timestamp:%lld field:%s",
204 (stream_ms / (60 * 60 * 1000)) % 24,
205 (stream_ms / (60 * 1000)) % 60,
206 (stream_ms / 1000) % 60,
207 stream_ms % 1000,
208 run->dst->sequence,
209 run->dst->vb2_buf.timestamp,
210 (run->dst->field == V4L2_FIELD_ALTERNATE) ?
211 (run->dst->field == V4L2_FIELD_TOP ?
212 " top" : " bottom") : "none");
213 }
214
visl_tpg_fill(struct visl_ctx * ctx,struct visl_run * run)215 static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run)
216 {
217 u8 *basep[TPG_MAX_PLANES][2];
218 char *buf = ctx->tpg_str_buf;
219 char *tmp = buf;
220 char *line_str;
221 u32 line = 1;
222 const u32 line_height = 16;
223 u32 len;
224 struct vb2_queue *out_q = &ctx->fh.m2m_ctx->out_q_ctx.q;
225 struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
226 struct v4l2_pix_format_mplane *coded_fmt = &ctx->coded_fmt.fmt.pix_mp;
227 struct v4l2_pix_format_mplane *decoded_fmt = &ctx->decoded_fmt.fmt.pix_mp;
228 u32 p;
229 u32 i;
230
231 for (p = 0; p < tpg_g_planes(&ctx->tpg); p++) {
232 void *vbuf = plane_vaddr(&ctx->tpg,
233 &run->dst->vb2_buf, p,
234 ctx->tpg.bytesperline,
235 ctx->tpg.buf_height);
236
237 tpg_calc_text_basep(&ctx->tpg, basep, p, vbuf);
238 tpg_fill_plane_buffer(&ctx->tpg, 0, p, vbuf);
239 }
240
241 visl_tpg_fill_sequence(ctx, run, buf, TPG_STR_BUF_SZ);
242 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
243 frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
244 frame_dprintk(ctx->dev, run->dst->sequence, "");
245 line++;
246
247 visl_get_ref_frames(ctx, buf, TPG_STR_BUF_SZ, run);
248
249 while ((line_str = strsep(&tmp, "\n")) && strlen(line_str)) {
250 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, line_str);
251 frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", line_str);
252 }
253
254 frame_dprintk(ctx->dev, run->dst->sequence, "");
255 line++;
256
257 scnprintf(buf,
258 TPG_STR_BUF_SZ,
259 "OUTPUT pixelformat: %c%c%c%c, resolution: %dx%d, num_planes: %d",
260 coded_fmt->pixelformat,
261 (coded_fmt->pixelformat >> 8) & 0xff,
262 (coded_fmt->pixelformat >> 16) & 0xff,
263 (coded_fmt->pixelformat >> 24) & 0xff,
264 coded_fmt->width,
265 coded_fmt->height,
266 coded_fmt->num_planes);
267
268 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
269 frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
270
271 for (i = 0; i < coded_fmt->num_planes; i++) {
272 scnprintf(buf,
273 TPG_STR_BUF_SZ,
274 "plane[%d]: bytesperline: %d, sizeimage: %d",
275 i,
276 coded_fmt->plane_fmt[i].bytesperline,
277 coded_fmt->plane_fmt[i].sizeimage);
278
279 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
280 frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
281 }
282
283 line++;
284 frame_dprintk(ctx->dev, run->dst->sequence, "");
285 scnprintf(buf, TPG_STR_BUF_SZ, "Output queue status:");
286 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
287 frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
288
289 len = 0;
290 for (i = 0; i < out_q->num_buffers; i++) {
291 char entry[] = "index: %u, state: %s, request_fd: %d, ";
292 u32 old_len = len;
293 char *q_status = visl_get_vb2_state(out_q->bufs[i]->state);
294
295 len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len,
296 entry, i, q_status,
297 to_vb2_v4l2_buffer(out_q->bufs[i])->request_fd);
298
299 len += visl_fill_bytesused(to_vb2_v4l2_buffer(out_q->bufs[i]),
300 &buf[len],
301 TPG_STR_BUF_SZ - len);
302
303 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]);
304 frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]);
305 }
306
307 line++;
308 frame_dprintk(ctx->dev, run->dst->sequence, "");
309
310 scnprintf(buf,
311 TPG_STR_BUF_SZ,
312 "CAPTURE pixelformat: %c%c%c%c, resolution: %dx%d, num_planes: %d",
313 decoded_fmt->pixelformat,
314 (decoded_fmt->pixelformat >> 8) & 0xff,
315 (decoded_fmt->pixelformat >> 16) & 0xff,
316 (decoded_fmt->pixelformat >> 24) & 0xff,
317 decoded_fmt->width,
318 decoded_fmt->height,
319 decoded_fmt->num_planes);
320
321 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
322 frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
323
324 for (i = 0; i < decoded_fmt->num_planes; i++) {
325 scnprintf(buf,
326 TPG_STR_BUF_SZ,
327 "plane[%d]: bytesperline: %d, sizeimage: %d",
328 i,
329 decoded_fmt->plane_fmt[i].bytesperline,
330 decoded_fmt->plane_fmt[i].sizeimage);
331
332 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
333 frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
334 }
335
336 line++;
337 frame_dprintk(ctx->dev, run->dst->sequence, "");
338 scnprintf(buf, TPG_STR_BUF_SZ, "Capture queue status:");
339 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf);
340 frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf);
341
342 len = 0;
343 for (i = 0; i < cap_q->num_buffers; i++) {
344 u32 old_len = len;
345 char *q_status = visl_get_vb2_state(cap_q->bufs[i]->state);
346
347 len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len,
348 "index: %u, status: %s, timestamp: %llu, is_held: %d",
349 cap_q->bufs[i]->index, q_status,
350 cap_q->bufs[i]->timestamp,
351 to_vb2_v4l2_buffer(cap_q->bufs[i])->is_held);
352
353 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]);
354 frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]);
355 }
356 }
357
visl_trace_ctrls(struct visl_ctx * ctx,struct visl_run * run)358 static void visl_trace_ctrls(struct visl_ctx *ctx, struct visl_run *run)
359 {
360 int i;
361
362 switch (ctx->current_codec) {
363 default:
364 case VISL_CODEC_NONE:
365 break;
366 case VISL_CODEC_FWHT:
367 trace_v4l2_ctrl_fwht_params(run->fwht.params);
368 break;
369 case VISL_CODEC_MPEG2:
370 trace_v4l2_ctrl_mpeg2_sequence(run->mpeg2.seq);
371 trace_v4l2_ctrl_mpeg2_picture(run->mpeg2.pic);
372 trace_v4l2_ctrl_mpeg2_quantisation(run->mpeg2.quant);
373 break;
374 case VISL_CODEC_VP8:
375 trace_v4l2_ctrl_vp8_frame(run->vp8.frame);
376 trace_v4l2_ctrl_vp8_entropy(run->vp8.frame);
377 break;
378 case VISL_CODEC_VP9:
379 trace_v4l2_ctrl_vp9_frame(run->vp9.frame);
380 trace_v4l2_ctrl_vp9_compressed_hdr(run->vp9.probs);
381 trace_v4l2_ctrl_vp9_compressed_coeff(run->vp9.probs);
382 trace_v4l2_vp9_mv_probs(&run->vp9.probs->mv);
383 break;
384 case VISL_CODEC_H264:
385 trace_v4l2_ctrl_h264_sps(run->h264.sps);
386 trace_v4l2_ctrl_h264_pps(run->h264.pps);
387 trace_v4l2_ctrl_h264_scaling_matrix(run->h264.sm);
388 trace_v4l2_ctrl_h264_slice_params(run->h264.spram);
389
390 for (i = 0; i < ARRAY_SIZE(run->h264.spram->ref_pic_list0); i++)
391 trace_v4l2_h264_ref_pic_list0(&run->h264.spram->ref_pic_list0[i], i);
392 for (i = 0; i < ARRAY_SIZE(run->h264.spram->ref_pic_list0); i++)
393 trace_v4l2_h264_ref_pic_list1(&run->h264.spram->ref_pic_list1[i], i);
394
395 trace_v4l2_ctrl_h264_decode_params(run->h264.dpram);
396
397 for (i = 0; i < ARRAY_SIZE(run->h264.dpram->dpb); i++)
398 trace_v4l2_h264_dpb_entry(&run->h264.dpram->dpb[i], i);
399
400 trace_v4l2_ctrl_h264_pred_weights(run->h264.pwht);
401 break;
402 case VISL_CODEC_HEVC:
403 trace_v4l2_ctrl_hevc_sps(run->hevc.sps);
404 trace_v4l2_ctrl_hevc_pps(run->hevc.pps);
405 trace_v4l2_ctrl_hevc_slice_params(run->hevc.spram);
406 trace_v4l2_ctrl_hevc_scaling_matrix(run->hevc.sm);
407 trace_v4l2_ctrl_hevc_decode_params(run->hevc.dpram);
408
409 for (i = 0; i < ARRAY_SIZE(run->hevc.dpram->dpb); i++)
410 trace_v4l2_hevc_dpb_entry(&run->hevc.dpram->dpb[i]);
411
412 trace_v4l2_hevc_pred_weight_table(&run->hevc.spram->pred_weight_table);
413 break;
414 }
415 }
416
visl_device_run(void * priv)417 void visl_device_run(void *priv)
418 {
419 struct visl_ctx *ctx = priv;
420 struct visl_run run = {};
421 struct media_request *src_req;
422
423 run.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
424 run.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
425
426 /* Apply request(s) controls if needed. */
427 src_req = run.src->vb2_buf.req_obj.req;
428
429 if (src_req)
430 v4l2_ctrl_request_setup(src_req, &ctx->hdl);
431
432 v4l2_m2m_buf_copy_metadata(run.src, run.dst, true);
433 run.dst->sequence = ctx->q_data[V4L2_M2M_DST].sequence++;
434 run.src->sequence = ctx->q_data[V4L2_M2M_SRC].sequence++;
435 run.dst->field = ctx->decoded_fmt.fmt.pix.field;
436
437 switch (ctx->current_codec) {
438 default:
439 case VISL_CODEC_NONE:
440 break;
441 case VISL_CODEC_FWHT:
442 run.fwht.params = visl_find_control_data(ctx, V4L2_CID_STATELESS_FWHT_PARAMS);
443 break;
444 case VISL_CODEC_MPEG2:
445 run.mpeg2.seq = visl_find_control_data(ctx, V4L2_CID_STATELESS_MPEG2_SEQUENCE);
446 run.mpeg2.pic = visl_find_control_data(ctx, V4L2_CID_STATELESS_MPEG2_PICTURE);
447 run.mpeg2.quant = visl_find_control_data(ctx,
448 V4L2_CID_STATELESS_MPEG2_QUANTISATION);
449 break;
450 case VISL_CODEC_VP8:
451 run.vp8.frame = visl_find_control_data(ctx, V4L2_CID_STATELESS_VP8_FRAME);
452 break;
453 case VISL_CODEC_VP9:
454 run.vp9.frame = visl_find_control_data(ctx, V4L2_CID_STATELESS_VP9_FRAME);
455 run.vp9.probs = visl_find_control_data(ctx, V4L2_CID_STATELESS_VP9_COMPRESSED_HDR);
456 break;
457 case VISL_CODEC_H264:
458 run.h264.sps = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_SPS);
459 run.h264.pps = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_PPS);
460 run.h264.sm = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
461 run.h264.spram = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_SLICE_PARAMS);
462 run.h264.dpram = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
463 run.h264.pwht = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_PRED_WEIGHTS);
464 break;
465 case VISL_CODEC_HEVC:
466 run.hevc.sps = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SPS);
467 run.hevc.pps = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_PPS);
468 run.hevc.spram = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SLICE_PARAMS);
469 run.hevc.sm = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SCALING_MATRIX);
470 run.hevc.dpram = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_DECODE_PARAMS);
471 break;
472 }
473
474 frame_dprintk(ctx->dev, run.dst->sequence,
475 "Got OUTPUT buffer sequence %d, timestamp %llu\n",
476 run.src->sequence, run.src->vb2_buf.timestamp);
477
478 frame_dprintk(ctx->dev, run.dst->sequence,
479 "Got CAPTURE buffer sequence %d, timestamp %llu\n",
480 run.dst->sequence, run.dst->vb2_buf.timestamp);
481
482 visl_tpg_fill(ctx, &run);
483 visl_trace_ctrls(ctx, &run);
484
485 if (bitstream_trace_frame_start > -1 &&
486 run.dst->sequence >= bitstream_trace_frame_start &&
487 run.dst->sequence < bitstream_trace_frame_start + bitstream_trace_nframes)
488 visl_trace_bitstream(ctx, &run);
489
490 /* Complete request(s) controls if needed. */
491 if (src_req)
492 v4l2_ctrl_request_complete(src_req, &ctx->hdl);
493
494 if (visl_transtime_ms)
495 usleep_range(visl_transtime_ms * 1000, 2 * visl_transtime_ms * 1000);
496
497 v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev,
498 ctx->fh.m2m_ctx, VB2_BUF_STATE_DONE);
499 }
500