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 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 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 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 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 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 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 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 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