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 < vb2_get_num_buffers(out_q); i++) { 291 char entry[] = "index: %u, state: %s, request_fd: %d, "; 292 u32 old_len = len; 293 struct vb2_buffer *vb2; 294 char *q_status; 295 296 vb2 = vb2_get_buffer(out_q, i); 297 if (!vb2) 298 continue; 299 300 q_status = visl_get_vb2_state(vb2->state); 301 302 len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len, 303 entry, i, q_status, 304 to_vb2_v4l2_buffer(vb2)->request_fd); 305 306 len += visl_fill_bytesused(to_vb2_v4l2_buffer(vb2), 307 &buf[len], 308 TPG_STR_BUF_SZ - len); 309 310 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]); 311 frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]); 312 } 313 314 line++; 315 frame_dprintk(ctx->dev, run->dst->sequence, ""); 316 317 scnprintf(buf, 318 TPG_STR_BUF_SZ, 319 "CAPTURE pixelformat: %c%c%c%c, resolution: %dx%d, num_planes: %d", 320 decoded_fmt->pixelformat, 321 (decoded_fmt->pixelformat >> 8) & 0xff, 322 (decoded_fmt->pixelformat >> 16) & 0xff, 323 (decoded_fmt->pixelformat >> 24) & 0xff, 324 decoded_fmt->width, 325 decoded_fmt->height, 326 decoded_fmt->num_planes); 327 328 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf); 329 frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf); 330 331 for (i = 0; i < decoded_fmt->num_planes; i++) { 332 scnprintf(buf, 333 TPG_STR_BUF_SZ, 334 "plane[%d]: bytesperline: %d, sizeimage: %d", 335 i, 336 decoded_fmt->plane_fmt[i].bytesperline, 337 decoded_fmt->plane_fmt[i].sizeimage); 338 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 343 line++; 344 frame_dprintk(ctx->dev, run->dst->sequence, ""); 345 scnprintf(buf, TPG_STR_BUF_SZ, "Capture queue status:"); 346 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, buf); 347 frame_dprintk(ctx->dev, run->dst->sequence, "%s\n", buf); 348 349 len = 0; 350 for (i = 0; i < vb2_get_num_buffers(cap_q); i++) { 351 u32 old_len = len; 352 struct vb2_buffer *vb2; 353 char *q_status; 354 355 vb2 = vb2_get_buffer(cap_q, i); 356 if (!vb2) 357 continue; 358 359 q_status = visl_get_vb2_state(vb2->state); 360 361 len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len, 362 "index: %u, status: %s, timestamp: %llu, is_held: %d", 363 vb2->index, q_status, 364 vb2->timestamp, 365 to_vb2_v4l2_buffer(vb2)->is_held); 366 367 tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]); 368 frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]); 369 } 370 } 371 372 static void visl_trace_ctrls(struct visl_ctx *ctx, struct visl_run *run) 373 { 374 int i; 375 376 switch (ctx->current_codec) { 377 default: 378 case VISL_CODEC_NONE: 379 break; 380 case VISL_CODEC_FWHT: 381 trace_v4l2_ctrl_fwht_params(run->fwht.params); 382 break; 383 case VISL_CODEC_MPEG2: 384 trace_v4l2_ctrl_mpeg2_sequence(run->mpeg2.seq); 385 trace_v4l2_ctrl_mpeg2_picture(run->mpeg2.pic); 386 trace_v4l2_ctrl_mpeg2_quantisation(run->mpeg2.quant); 387 break; 388 case VISL_CODEC_VP8: 389 trace_v4l2_ctrl_vp8_frame(run->vp8.frame); 390 trace_v4l2_ctrl_vp8_entropy(run->vp8.frame); 391 break; 392 case VISL_CODEC_VP9: 393 trace_v4l2_ctrl_vp9_frame(run->vp9.frame); 394 trace_v4l2_ctrl_vp9_compressed_hdr(run->vp9.probs); 395 trace_v4l2_ctrl_vp9_compressed_coeff(run->vp9.probs); 396 trace_v4l2_vp9_mv_probs(&run->vp9.probs->mv); 397 break; 398 case VISL_CODEC_H264: 399 trace_v4l2_ctrl_h264_sps(run->h264.sps); 400 trace_v4l2_ctrl_h264_pps(run->h264.pps); 401 trace_v4l2_ctrl_h264_scaling_matrix(run->h264.sm); 402 trace_v4l2_ctrl_h264_slice_params(run->h264.spram); 403 404 for (i = 0; i < ARRAY_SIZE(run->h264.spram->ref_pic_list0); i++) 405 trace_v4l2_h264_ref_pic_list0(&run->h264.spram->ref_pic_list0[i], i); 406 for (i = 0; i < ARRAY_SIZE(run->h264.spram->ref_pic_list0); i++) 407 trace_v4l2_h264_ref_pic_list1(&run->h264.spram->ref_pic_list1[i], i); 408 409 trace_v4l2_ctrl_h264_decode_params(run->h264.dpram); 410 411 for (i = 0; i < ARRAY_SIZE(run->h264.dpram->dpb); i++) 412 trace_v4l2_h264_dpb_entry(&run->h264.dpram->dpb[i], i); 413 414 trace_v4l2_ctrl_h264_pred_weights(run->h264.pwht); 415 break; 416 case VISL_CODEC_HEVC: 417 trace_v4l2_ctrl_hevc_sps(run->hevc.sps); 418 trace_v4l2_ctrl_hevc_pps(run->hevc.pps); 419 trace_v4l2_ctrl_hevc_slice_params(run->hevc.spram); 420 trace_v4l2_ctrl_hevc_scaling_matrix(run->hevc.sm); 421 trace_v4l2_ctrl_hevc_decode_params(run->hevc.dpram); 422 423 for (i = 0; i < ARRAY_SIZE(run->hevc.dpram->dpb); i++) 424 trace_v4l2_hevc_dpb_entry(&run->hevc.dpram->dpb[i]); 425 426 trace_v4l2_hevc_pred_weight_table(&run->hevc.spram->pred_weight_table); 427 break; 428 } 429 } 430 431 void visl_device_run(void *priv) 432 { 433 struct visl_ctx *ctx = priv; 434 struct visl_run run = {}; 435 struct media_request *src_req; 436 437 run.src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); 438 run.dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 439 440 /* Apply request(s) controls if needed. */ 441 src_req = run.src->vb2_buf.req_obj.req; 442 443 if (src_req) 444 v4l2_ctrl_request_setup(src_req, &ctx->hdl); 445 446 v4l2_m2m_buf_copy_metadata(run.src, run.dst, true); 447 run.dst->sequence = ctx->q_data[V4L2_M2M_DST].sequence++; 448 run.src->sequence = ctx->q_data[V4L2_M2M_SRC].sequence++; 449 run.dst->field = ctx->decoded_fmt.fmt.pix.field; 450 451 switch (ctx->current_codec) { 452 default: 453 case VISL_CODEC_NONE: 454 break; 455 case VISL_CODEC_FWHT: 456 run.fwht.params = visl_find_control_data(ctx, V4L2_CID_STATELESS_FWHT_PARAMS); 457 break; 458 case VISL_CODEC_MPEG2: 459 run.mpeg2.seq = visl_find_control_data(ctx, V4L2_CID_STATELESS_MPEG2_SEQUENCE); 460 run.mpeg2.pic = visl_find_control_data(ctx, V4L2_CID_STATELESS_MPEG2_PICTURE); 461 run.mpeg2.quant = visl_find_control_data(ctx, 462 V4L2_CID_STATELESS_MPEG2_QUANTISATION); 463 break; 464 case VISL_CODEC_VP8: 465 run.vp8.frame = visl_find_control_data(ctx, V4L2_CID_STATELESS_VP8_FRAME); 466 break; 467 case VISL_CODEC_VP9: 468 run.vp9.frame = visl_find_control_data(ctx, V4L2_CID_STATELESS_VP9_FRAME); 469 run.vp9.probs = visl_find_control_data(ctx, V4L2_CID_STATELESS_VP9_COMPRESSED_HDR); 470 break; 471 case VISL_CODEC_H264: 472 run.h264.sps = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_SPS); 473 run.h264.pps = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_PPS); 474 run.h264.sm = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX); 475 run.h264.spram = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_SLICE_PARAMS); 476 run.h264.dpram = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS); 477 run.h264.pwht = visl_find_control_data(ctx, V4L2_CID_STATELESS_H264_PRED_WEIGHTS); 478 break; 479 case VISL_CODEC_HEVC: 480 run.hevc.sps = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SPS); 481 run.hevc.pps = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_PPS); 482 run.hevc.spram = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SLICE_PARAMS); 483 run.hevc.sm = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_SCALING_MATRIX); 484 run.hevc.dpram = visl_find_control_data(ctx, V4L2_CID_STATELESS_HEVC_DECODE_PARAMS); 485 break; 486 } 487 488 frame_dprintk(ctx->dev, run.dst->sequence, 489 "Got OUTPUT buffer sequence %d, timestamp %llu\n", 490 run.src->sequence, run.src->vb2_buf.timestamp); 491 492 frame_dprintk(ctx->dev, run.dst->sequence, 493 "Got CAPTURE buffer sequence %d, timestamp %llu\n", 494 run.dst->sequence, run.dst->vb2_buf.timestamp); 495 496 visl_tpg_fill(ctx, &run); 497 visl_trace_ctrls(ctx, &run); 498 499 if (bitstream_trace_frame_start > -1 && 500 run.dst->sequence >= bitstream_trace_frame_start && 501 run.dst->sequence < bitstream_trace_frame_start + bitstream_trace_nframes) 502 visl_trace_bitstream(ctx, &run); 503 504 /* Complete request(s) controls if needed. */ 505 if (src_req) 506 v4l2_ctrl_request_complete(src_req, &ctx->hdl); 507 508 if (visl_transtime_ms) 509 usleep_range(visl_transtime_ms * 1000, 2 * visl_transtime_ms * 1000); 510 511 v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev, 512 ctx->fh.m2m_ctx, VB2_BUF_STATE_DONE); 513 } 514